È possibile assegnare un indirizzo univoco per una variabile constexpr, vale a dire lo stesso per tutte le unità di traduzione in cui la variabile è disponibile (di solito attraverso un'intestazione)? Si consideri il seguente esempio:Indirizzo univoco per variabile constexpr
// foo.hh
#include <iostream>
constexpr int foo = 42;
// a.cc
#include "foo.hh"
void a(void) { std::cout << "a: " << &foo << std::endl; }
// b.cc
#include "foo.hh"
extern void a(void);
int main(int argc, char** argv) {
a();
std::cout << "b: " << &foo << std::endl;
}
Compilazione a.cc
e b.cc
separatamente, e collegandoli tra loro con gcc 4.7, vedo due indirizzi diversi stampati. Se aggiungo la parola chiave extern
nell'intestazione, ottengo un errore del linker duplicate symbol _foo in: a.o and b.o
che trovo un po 'sorprendente, perché pensavo che l'aggiunta di extern
avrebbe più probabilmente indotto il compilatore a importare quel simbolo da un altro oggetto invece di esportarlo dall'oggetto corrente . Ma sembra che la mia comprensione di come funzionano le cose qui è sbagliata.
Esiste un modo ragionevole per dichiarare un constexpr in un'intestazione, in modo che tutte le unità di traduzione possano utilizzarlo nelle loro espressioni costanti e in modo tale che tutte le unità di traduzione concordino sull'indirizzo di tale simbolo? Mi aspetto un codice aggiuntivo per indicare la singola unità di traduzione a cui questo simbolo appartiene, esattamente come con le variabili extern
e non extern
senza constexpr
.
Credo che il tuo 'foo' abbia un collegamento interno, quindi stai vedendo due copie separate. La solita soluzione per il tuo problema è avere un 'extern const int foo' dichiarato nell'intestazione e implementato come' const int foo = 42; 'in * one * translation unit. Ma spesso non può essere un'espressione costante, dal momento che 'int a [foo]' deve essere risolvibile al momento della compilazione, e non solo al momento del collegamento. –
Forse c'è un altro modo per ottenere ciò che stai cercando di fare. Quindi ... cosa * esattamente * stai cercando di fare con questo indirizzo? –
@NicolBolas: Finora sto cercando di fare i conti con 'constexpr' in generale.Avevo l'abitudine di usare il collegamento esterno per le variabili globali di 'const' per evitare l'allocazione di memoria duplicata anche se qualcuno decidesse di prendere un indirizzo di tale bestia. Ora con 'constexpr' questo non sembra più possibile. Quindi quello che sto cercando di scoprire è se c'è un modo per evitare la duplicazione dei dati anche se qualche codice strano che non riesco a immaginare in questo momento decide di prendere indirizzi di queste cose dappertutto. – MvG