Domanda

Ho una funzione che richiede molto * ed esigenze senza segno di passare ad una libreria esterna che accetta un unsigned int * e su questa piattaforma int unsigned / lungo hanno la stessa dimensione.

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

Questo genera un avviso dicendo che la sua rottura regole severe-aliasing. Ci sono arounds di lavoro?

Grazie

Edit: mi scuso per non essere chiaro. Il codice è un aggiornamento atomica in modo da andare in giro per la libreria per memorizzare non è un'opzione. Potrei scendere fino a assemblaggio, ma mi piacerebbe fare questo in C ++.

È stato utile?

Soluzione

void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}

Altri suggerimenti

Questo dovrebbe funzionare:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}

Niente nei mandati C standard che int e long devono avere le stesse dimensioni; inoltre, anche se hanno la stessa dimensione, nulla nei mandati standard che hanno la stessa rappresentazione (tra le altre cose, che potrebbero avere combinazioni incompatibili di bit di riempimento e rappresentazioni trappola, tale che aliasing tra i due tipi non può servire qualsiasi scopo utile).

Gli autori dello standard non ha voluto per forza esecutori mirati piattaforme dove aliasing tra int e long non servirebbe a nulla per riconoscere quali aliasing. Inoltre non hanno voglia di scrivere le regole che sarebbero applicabili ad alcune piattaforme (quelle in cui aliasing servirebbe uno scopo), ma non altri (quelli in cui non sarebbe). Al contrario, hanno pensato che le persone che scrivono i compilatori di qualità avrebbero cercato di riconoscere aliasing nei casi in cui era utile.

Essere in grado di utilizzare i puntatori a un tipo a 32-bit per leggere e scrivere i valori di un altro tipo a 32-bit che ha la stessa rappresentazione è chiaramente utile, soprattutto se le API sono divisa su quale tipo che si aspettano. Se alcune API banale su un int* uso della piattaforma per i valori a 32 bit e altri usano long*, un qualità implementazione general-purpose per quella piattaforma deve consentire i dati di entrambi i tipi a cui accedere utilizzando i puntatori dell'altra.

Purtroppo, però, di alcuni compilatori gli autori sono più interessati a elaborazione di un certo sottoinsieme di programmi in fretta, che in elaborazione di un più ampio sottogruppo di programmi utilmente, e non possono essere invocate per generare il codice utile se è necessario lo scambio di dati tra API che utilizzano la stessa rappresentazione dei dati, ma diversi tipi di nome a meno che uno disabilita completamente aliasing analisi. Naturalmente, se uno si rivolge dialetti di C che sono adatti per l'uso generico su microcontrollori, tali questioni non contano.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top