2016-05-12 13 views
7

Recentemente sono stato sorpreso di apprendere che gli standard di linguaggio C e C++ hanno una regola di "aliasing rigoroso". In sostanza, la regola proibisce alle variabili di tipi diversi di fare riferimento alla stessa posizione di memoria.Visual C++ supporta "aliasing rigoroso"?

Per fare un esempio:

char buffer[4] = { 0x55, 0x66, 0x77, 0x88 }; 
int32 *p = (int32*)&buffer[0]; // illegal because buffer[0] and *p are different types 

La maggior parte degli sviluppatori professionisti C++ con cui interagisco non hanno familiarità con questa regola. Sulla base della mia ricerca, sembra interessare principalmente gli utenti GCC/G ++/CLANG. Visual C++ supporta l'abilitazione/disabilitazione di questa regola? Se è così, come si fa?

Grazie

+0

AFAIK MSVC si comporta sempre come se si impostasse il no-strict-aliasing –

+3

È un compilatore con un telefono di supporto 1-800 numero. Quindi no. –

+1

lol @ con un numero di supporto 1-800 :) – digitale

risposta

6

"aliasing Strict" è una regola C++ limitando i programmi, non compilatori. Poiché la violazione della regola è Comportamento non definito, non è richiesta alcuna diagnostica un compilatore non ha bisogno di supportarlo in alcun modo.

Detto questo, Microsoft è un po 'meno aggressiva nell'applicare le ottimizzazioni. Solo la scorsa settimana hanno annunciato il loro nuovo ottimizzatore assumes no signed overflow, qualcosa che GCC ha assunto già da alcuni anni. Aliasing severo sta per rompere alcune intestazioni di Windows, quindi è necessario correggerle per prime. (Alcuni tipi si comportano come se contengano union s, ma non sono formalmente definiti come tali)

+1

Sarebbe utile, IMHO, se esistesse un mezzo attraverso il quale i compilatori potrebbero promettere di utilizzare la semantica di interi in modo tale che il risultato di un'addizione, sottrazione o moltiplicazione di un intero n bit si comporterebbe sempre come un intero che è congruente a 2ⁿ, ma in caso di overflow la scelta di * quale * numero intero potrebbe essere non deterministico. Il codice che potrebbe fare affidamento su tali limiti comportamentali potrebbe in molti casi essere più efficiente del codice che doveva impedire gli overflow a tutti i costi. – supercat

+0

@supercat: non sono sicuro di aver davvero bisogno di aiuto per il compilatore; sembra che tu possa implementarlo in una biblioteca. Usa 'unsigned' internamente; le sue operazioni corrispondono quasi 1: 1 con il complemento aritmetico del complemento a 2. – MSalters

+1

Si potrebbe scrivere una libreria per eseguire tali calcoli in modo tale da ottenere sempre un risultato nell'intervallo di 'int', ma forzare il comportamento di avvolgimento - tramite codice o opzioni del compilatore - può essere un importante ostacolo all'efficienza. Se un programmatore deve forzare il comportamento del wrapping per essere in grado di evitare che un compilatore salti le rotaie, spesso impedirà a un compilatore di generare codice efficiente come quello che potrebbe generare se avesse la libertà di ignorare il wrapping (ad esempio dato 'i + x> y', se 'x' e' y' sono loop-invariant, un compilatore potrebbe usare un ciclo per il caso in cui 'yx' non traboccherebbe ... – supercat