DOCUMENT:Q123461 25-JUL-2001 [visualc] TITLE :PRB: const char* not same as const CPTR where #typedef char* C PRODUCT :Microsoft C Compiler PROD/VER::2.0,2.1,4.0,5.0,6.0 OPER/SYS: KEYWORDS:kbCompiler kbVC200 kbVC210 kbVC400 kbVC500 kbVC600 ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - The C/C++ Compiler (CL.EXE), included with: - Microsoft Visual C++, 32-bit Editions, versions 2.0, 2.1, 4.0 - Microsoft Visual C++, 32-bit Enterprise Edition, version 5.0 - Microsoft Visual C++, 32-bit Professional Edition, version 5.0 - Microsoft Visual C++, 32-bit Enterprise Edition, version 6.0 - Microsoft Visual C++, 32-bit Professional Edition, version 6.0 - Microsoft Visual C++, 32-bit Learning Edition, version 6.0 ------------------------------------------------------------------------------- SYMPTOMS ======== The following program compiles, but one of the following warnings appears: C4090: 'initializing' : different 'const' qualifiers: -or- C2440: 'initializing' : cannot convert from 'const char *' to 'char *' Conversion loses qualifiers const char *ReturnConstantPtr() { const char *p = "can't touch this"; return p; } void main() { char *p = ReturnConstantPtr(); } However, the above program will compile without exception if a type definition is used for char* as follows: typedef char* CPTR; const CPTR ReturnConstantPtr() { const CPTR p = "can't touch this"; return p; } void main() { CPTR p = ReturnConstantPtr(); } CAUSE ===== This occurs for two reasons. First, typedefs are not macros, so modifiers like const or volatile apply to the whole construct. When the following are used #typedef char* CPTR const CPTR cPtr; they are equivalent to "char* const cPtr;" not "const char* cPtr;." Second, since "char* const cPtr;" declares cPtr as a constant pointer to character data and "const char* cPtr;" declares cPtr as a pointer to constant character data, the two declarations are quite different. Thus, a "different const qualifier" warning is generated for char *p = ReturnConstantPtr(); because it is trying to set p equal to a pointer that points to a constant character whose value *p could try to change. Alternatively, no warning is generated for CPTR p = ReturnConstantPtr(); because it is setting p equal to a constant pointer that points to a character whose value *p may freely change. REFERENCES ========== For more information on the const keyword, search the online documentation provided with Visual C++, 32-bit edition, for "const" or "constant values." For more information on the typedef keyword, search the online documentation for "#typedef" or "typedef specifier." Additional query words: 9.00 ====================================================================== Keywords : kbCompiler kbVC200 kbVC210 kbVC400 kbVC500 kbVC600 Technology : kbVCsearch kbAudDeveloper kbCVCComp Version : :2.0,2.1,4.0,5.0,6.0 Issue type : kbprb ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2001.