2013-09-05 10 views
11

Während diese kompiliert:zuweisen Zeiger auf Zeiger mit oder ohne Qualifikations

char* p2c; 
const char* p2cc = p2c; //fine 

weil lhs spitzen Typ alle Qualifier von rhs spitzen Typ hat, dies nicht:

char** p2p2c; 
const char** p2p2cc = p2p2c; //fail 

aber dies tut:

const char * const * p2cp2cc = p2p2c; //fine 

Warum genau passiert das?

+1

Das letzte Beispiel kompiliert nur in C++, aber nicht in C. – AnT

+0

@AndreyT warum so? – emesx

+0

Genau so ist es in C und C++. Dies sind zwei verschiedene Sprachen mit unterschiedlichen Konstanten für die Korrektheit. In C++ ist 'T **' konvertierbar nach 'const T * const *'. In C 'T **' ist konvertierbar in 'T * const *', aber nicht in 'T * const *'. http://StackOverflow.com/a/5249001/187690 – AnT

Antwort

7

funktioniert das nicht:

char** p2p2c; 
const char** p2p2cc = p2p2c; //fail 

Wenn das durfte man const-Korrektheit zu brechen erlaubt sein würde:

const int k = 10; 
int *p; 
int **pp = &p; 
int const **kpp = pp;  // Should this be allowed, if so: 
*kpp = &k;    // fine, kpp promises not to change it 
          // yet this does p = &k; 
          // p made no such promise! this is a hidden const_cast! 
*p = 5; 

Wenn die Zuweisung erlaubt wurde, würde es Ihnen ermöglichen, Setzen eines nichtkonstanten Zeigers (intermediate), um auf einen konstanten Wert zu verweisen, was möglicherweise undefiniertes Verhalten in einem nicht offensichtlichen Weg verursacht. Durch das Verbot dieser Operation ist das Typsystem sicherer.

aber dies tut:

const char * const * p2cp2cc = p2p2c; //fine 

Das ist in Ordnung, da die Zwischenzeiger befestigt ist, ist es unmöglich, den Zwischen Zeiger zurückgesetzt auf ein konstantes Objekt zu beziehen und brechen const-Korrektheit

+0

Warum kann man 'char **' in 'char const * const *' sicher konvertieren? – emesx

+0

@elmes: Da der Zwischenzeiger auch 'const 'ist, bedeutet das, dass Sie ihn nicht auf das * wrong * -Objekt zurücksetzen können. –

+0

Scheint jetzt ganz in Ordnung, danke. – emesx

-1

cdecl hilft wirklich in Fällen wie diesem.

const char** p2p2cc = declare p2p2cc as pointer to pointer to const char 

und

const char * const * p2cp2cc = declare p2cp2cc as pointer to const pointer to const char 

Wie Sie sehen können, ist die zweite Version hat die innere und die äußere Zeiger const, dh es ist auch nicht ändern können. Die erste Version hat den INNER-Zeiger const und den äußeren non-const, wodurch constnes gebrochen wird.

Auf der anderen Seite, das funktioniert:

char** const p = p2p2c; 
Verwandte Themen