FIX: Error C2664 Generated with Class Created by TEMPLDEF

Last reviewed: September 18, 1997
Article ID: Q114833
1.00 1.50 WINDOWS kbprg kbfixlist kbbuglist

The information in this article applies to:

  • The Microsoft Foundation Classes (MFC) included with:

        - Microsoft Visual C++ for Windows, versions 1.0 and 1.5
    

SYMPTOMS

When a user-defined MFC collection class of the form

   CMap<any type>toString

is generated using the TEMPLDEF utility and when the class is compiled with /AS or /AM, for small or medium memory model, the compiler generates the following error message:

   error C2664: 'ConstructElement' : cannot convert parameter 1 from
      'unsigned short __near *' to 'class ::CString __near *'

If the code was compiled with /AL or /AC, for large or compact memory model, the error message contains __far instead of __near, because in these memory models, pointers are far pointers by default.

CAUSE

The TEMPLDEF utility is passed several parameters to create a new collection class. One of these is HAS_CREATE. The following code is inserted into the newly created class code if HAS_CREATE is defined:

        ASSERT(m_nCount > 0);  // make sure we don't overflow
        memset(&pAssoc->key, 0, sizeof(KEY));
#if HAS_CREATE
        ConstructElement(&pAssoc->key);  // special construct values

When creating a Map<Type>toString class, HAS_CREATE is defined. The ConstructElement() function is only used with CStrings and is defined in the header file ELEMENTS.H. Creating a CMapWordtoString class would use the MAP.CTT template. The code listed above is from the MAP.CTT template.

The only class that maps from CStrings is CMapStringToString. This class is expanded from MAP_S.CTT. The code from MAP_S.CTT is:

        ASSERT(m_nCount > 0);  // make sure we don't overflow
        memcpy(&pAssoc->key, &afxEmptyString, sizeof(CString));
#if HAS_CREATE
        ConstructElement(&pAssoc->value);
#else
        memset(&pAssoc->value, 0, sizeof(VALUE));
#endif

Notice that the ConstructElement() parameter in MAP_S.CTT is the value member of pAssoc if HAS_CREATE is defined (instead of the key member as listed in MAP.CTT). Passing key to ConstructElement() is sure to fail in the case of CMap<TYPE>toString because key is declared as WORD and ConstructElement() expects a CString*.

RESOLUTION

Change the source file containing the call to ConstructElement() so that it is passed the value field of pAssoc. It should look like:

   ConstructElement(&pAssoc->value);

STATUS

Microsoft has confirmed this to be a bug in the Microsoft Foundation Classes, versions 2.0 and 2.5. This problem was corrected in MFC version 3.0, included with Visual C++ version 2.0.

MORE INFORMATION

In order to reproduce the problem, copy all of the following lines to MKCOLL.BAT:

   templdef "CMap<WORD, WORD, CString, const char*,1,1> CMapWordtoString"
   map.ctt temp.h temp.inl map_ws.cpp
   copy newcoll.h+temp.h newcoll.h
   copy newcoll.inl+temp.inl newcoll.inl


Additional reference words: 1.00 1.50 2.00 2.50
KBCategory: kbprg kbfixlist kbbuglist
KBSubcategory: MfcMisc
Keywords : kb16bitonly MfcMisc kbbuglist kbfixlist kbprg
Technology : kbMfc
Version : 1.00 1.50
Platform : WINDOWS
Solution Type : kbfix


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.

Last reviewed: September 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.