Thread: Error C2040: ... differs in levels of indirection from ... MXVC++ Problem # 1

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    4

    Error C2040: ... differs in levels of indirection from ... MXVC++ Problem # 1

    I am posting two threads because I have two different problems, but both have the same background information.

    Common Background Information:

    I am trying to rebuild code for a working, commercially sold application with only partial build instructions. The previous maintainer of the code (a mixture of C and C++) is no longer with the company, but when he built the code he used MSVC++, and though I am not certain of the version he was using, I think it was either 4.0 or 6.0. I have only a little experience building with this environment (I am otherwise a seasoned developer) so I need help getting past a couple of issues that I have encountered. Computers (and backups of those computers) previously used for running this build are now completely unavailable.

    I have set up the build on my system using MSVC++ 6.0. The source repository contained a workspace (.dsw) file that I am using for all of the projects. I do not have specific instructions for this product on how to adjust the references to libraries, includes, etc. for a particular machine, but I am using instructions for this from a similar (in terms of languages and tools used) product that was written around the same time. I have gotten 43 of 53 classes (projects) to build, but am getting primarily two errors with the remaining 10 clases (projects).

    Because I know this code base was building properly (for someone else who is no longer available on a machine that is no longer available), I would strongly prefer adjustments to the build environment over code modification to get it to work, so please focus your assistance/suggestions in this area.

    Thanks !

    Problem #1: Error C2040: ... differs in levels of indirection from ...

    Here are the exact error messages I am receiving:

    Fxactn.cpp
    \develop\3rdParty\xvtdsp45\w32_x86\include\xvt_typ e.h(54) : error C2040: 'LONG_PTR' : 'long *' differs in levels of indirection from 'long'
    \develop\3rdParty\xvtdsp45\w32_x86\include\xvt_typ e.h(55) : error C2040: 'ULONG_PTR' : 'unsigned long *' differs in levels of indirection from 'unsigned long'
    Fxapifun.cpp
    C:\PROGRAM FILES\MICROSOFT SDK\INCLUDE\basetsd.h(92) : error C2040: 'LONG_PTR' : 'long' differs in levels of indirection from 'long *'
    C:\PROGRAM FILES\MICROSOFT SDK\INCLUDE\basetsd.h(93) : error C2040: 'ULONG_PTR' : 'unsigned long' differs in levels of indirection from 'unsigned long *'
    Guicinit.cpp
    \develop\3rdParty\xvtdsp45\w32_x86\include\xvt_typ e.h(54) : error C2040: 'LONG_PTR' : 'long *' differs in levels of indirection from 'long'
    \develop\3rdParty\xvtdsp45\w32_x86\include\xvt_typ e.h(55) : error C2040: 'ULONG_PTR' : 'unsigned long *' differs in levels of indirection from 'unsigned long'
    The first two errors and the last two errors come from the same include file. I put the errors twice simply to emphasize that I am receiving these errors on multiple source files. The middle two errors are only occurring once.

    Here are lines 41 through 58 of xvt_type.h (apparently a third party include file):

    Code:
    typedef unsigned short T_LNUM;
    typedef unsigned short T_PNUM;
    typedef unsigned long  XVT_COLOR_TYPE; /* Color Component Type (XVT_COLOR_* */
    
    /* The following legacy "data types" are being phased out, as they cause    */
    /* problems with constness: "const int *x" is NOT same as "const INT_PTR x" */
    //typedef int           *INT_PTR;
    typedef BOOLEAN       *BOOLEAN_PTR;
    typedef char           XVT_BYTE;    /* raw data */
    typedef unsigned char  XVT_UBYTE;   /* raw data */
    typedef XVT_BYTE      *DATA_PTR;    /* ptr to arbitrary data - backwards compat. */
    typedef XVT_UBYTE     *UDATA_PTR;   /* unsigned ptr to arbitrary data */
    typedef XVT_UBYTE      DATA_BYTE;   /* for raw data */
    typedef long          *LONG_PTR;          /* THIS IS LINE 54 */
    typedef unsigned long *ULONG_PTR;        /* THIS IS LINE 55 */
    
    /* define a point to function which will be used in xvt_win_enum_wins etc. */
    typedef XVT_CALLCONV_TYPEDEF( BOOLEAN, XVT_ENUM_CHILDREN, (WINDOW child, long data));
    Here are the first 98 lines of the BaseTsd.h file:

    Code:
    /*++
    
    Copyright (c) Microsoft Corporation.  All rights reserved.
    
    Module Name:
    
        basetsd.h
    
    Abstract:
    
        Type definitions for the basic sized types.
    
    Author:
    
    Revision History:
    
    --*/
    
    #ifndef _BASETSD_H_
    #define _BASETSD_H_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    typedef signed char         INT8, *PINT8;
    typedef signed short        INT16, *PINT16;
    typedef signed int          INT32, *PINT32;
    typedef signed __int64      INT64, *PINT64;
    typedef unsigned char       UINT8, *PUINT8;
    typedef unsigned short      UINT16, *PUINT16;
    typedef unsigned int        UINT32, *PUINT32;
    typedef unsigned __int64    UINT64, *PUINT64;
    
    //
    // The following types are guaranteed to be signed and 32 bits wide.
    //
    
    typedef signed int LONG32, *PLONG32;
    
    //
    // The following types are guaranteed to be unsigned and 32 bits wide.
    //
    
    typedef unsigned int ULONG32, *PULONG32;
    typedef unsigned int DWORD32, *PDWORD32;
    
    #if !defined(_W64)
    #if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
    #define _W64 __w64
    #else
    #define _W64
    #endif
    #endif
    
    //
    // The INT_PTR is guaranteed to be the same size as a pointer.  Its
    // size with change with pointer size (32/64).  It should be used
    // anywhere that a pointer is cast to an integer type. UINT_PTR is
    // the unsigned variation.
    //
    // __int3264 is intrinsic to 64b MIDL but not to old MIDL or to C compiler.
    //
    #if ( 501 < __midl )
    
        typedef [public] __int3264 INT_PTR, *PINT_PTR;
        typedef [public] unsigned __int3264 UINT_PTR, *PUINT_PTR;
    
        typedef [public] __int3264 LONG_PTR, *PLONG_PTR;
        typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
    
    #else  // midl64
    // old midl and C++ compiler
    
    #if defined(_WIN64)
        typedef __int64 INT_PTR, *PINT_PTR;
        typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
    
        typedef __int64 LONG_PTR, *PLONG_PTR;
        typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
    
        #define __int3264   __int64
    
    #else
        typedef _W64 int INT_PTR, *PINT_PTR;
        typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
    
        typedef _W64 long LONG_PTR, *PLONG_PTR;
        typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
    
        #define __int3264   __int32
    
    #endif
    #endif // midl64
    My thoughts so far are as follows:

    1. One possibility is that the previous builder of this code precompiled these (and probably all 3rd party and MS) headers separately using a different environment or different settings prior to the build, and he had the pre-compiled headers available when he ran the main build, so he would not have gotten these errors.
    2. Another possibility is that the previous builder was using different settings for the compile than I am using -- perhaps a older version compatability flag or something like that. However, if this was on the main build (as opposed to a separate run to precompile header files) I would expect that setting to be in the saved workspace (.dsw) file.
    3. The only other possibility that I have been able to come up with is that the previous builder was using or pointing to a later version of these header files than I am. I will look into this possibility, but I wanted to go ahead and post to get the ball rolling first, in case someone else had other helpful ideas.


    Any thoughts or suggestions from an experienced MSVC++ user would be greatly appreciated.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    This line
    Code:
    typedef _W64 long LONG_PTR, *PLONG_PTR;
    can't be right, I don't think. LONG_PTR generally means pointer to long, right? And that's how the first code snippet defined it. But here it's typedef'ed as just a long. Which is where the complaints come from, as you're trying to define LONG_PTR two different ways.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    I think the naming may be a bit dubious, but LONG_PTR is actually "a long that matches a pointer in size", so not a pointer to long. PLONG_PTR is a pointer to such a variable - and don't shoot the messenger, I had absolutely no influence in MS's choice of names...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by matsp View Post
    I think the naming may be a bit dubious, but LONG_PTR is actually "a long that matches a pointer in size", so not a pointer to long. PLONG_PTR is a pointer to such a variable - and don't shoot the messenger, I had absolutely no influence in MS's choice of names...

    --
    Mats
    Oh I had missed that was an MS base file. Well. At any rate, we have a difference of opinion about what "LONG_PTR" should mean: your third-party thinks it means "pointer to long" while MS thinks it means "pointer-sized long". In any event, if this had compiled before, then they weren't included at the same time, or some magic must have been done. (I can't think of anything that allows you to un-typedef something like #undef?)

    Do you use LONG_PTR in your code? Which one does it mean? (And if it means "both", heaven help us all.)

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Just a little background on the error:
    It comes from code such as this:
    Code:
    long y;
    long* x;
    y = x;
    You can't assign a long* to a long or vice versa (at least not without a cast, but it's doubtful if it's right to do so).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Ex scientia vera
    Join Date
    Sep 2007
    Posts
    477
    Quote Originally Posted by matsp View Post
    I think the naming may be a bit dubious, but LONG_PTR is actually "a long that matches a pointer in size", so not a pointer to long. PLONG_PTR is a pointer to such a variable - and don't shoot the messenger, I had absolutely no influence in MS's choice of names...

    --
    Mats
    Just out of curiosity, why would anyone even want a "pointer-sized long" ? What is the use for that kind of variable / size definition?
    "What's up, Doc?"
    "'Up' is a relative concept. It has no intrinsic value."

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by IceDane View Post
    Just out of curiosity, why would anyone even want a "pointer-sized long" ? What is the use for that kind of variable / size definition?
    The WinAPI (and other legacy C APIs) is full of places where the user can pass some kind of parameter to a function that will be passed through, unmodified, to some callback, or will be able for retrieval later. This is done so that the user can pass some context along. C++ wrappers will often use this to pass the this pointer of the context object.

    Such parameters should always be at least large enough to accommodate a pointer. At the same time, however making it an integer type is attractive too, for some reason. (Can't think of why, but it's very common.) Therefore you need an integer type that is definitely large enough to hold a pointer. LONG_PTR is such a type. Other such types are ULONG_PTR, INT_PTR and UINT_PTR, all from the WinAPI, or the C99 standard intptr_t and uintptr_t.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Indeed, as CornedBee says.

    You may want to pass the "this-pointer of your class".

    But it may also be some simple value representing (for example) which item in some array it is. Sure you COULD pass the address of the variable instead, but you actually want to pass whatever it is in the call-back to a function that has as an input parameter an index to that array.

    You definitely want such a parameter to be the same size as an pointer - or it will break when passing a 64-bit pointer on when "long" or "int" is 32 bit.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  9. #9
    Registered User
    Join Date
    Jun 2009
    Posts
    4

    This is an update from the original poster....

    First of all, I want to clarify one item. I did not include all error messages in the original post. When I try to build some projects I only get the error involving xvt_type.h. There is only one project that gives me both the xvt_type.h error and the basetsd.h error, but even in that case it is trying to compile different source files. Thus, I don't think suggestions that the errors are caused by conflicts between xvt_type.h and basetsd.h hold water.

    Secondly, in response to suggestions that I have received regarding changing the order of include and library directory searches... I have tried several different orders with no noticeable impact. The order I have right now is Microsoft SDK first, third party includes and libraries second, and VC98 includes and libraries last. This seems the safest, but again no order seems to work (trying every single permutation would take quite a while.)

    Thirdly, in regards to the suggestion that I received that I might need older MS header files (and another that suggested that the basetsd.h that I quoted in my post looked like it might be from VC++ 2008 instead of from MSVC++ 6.0), let me say that the basetsd.h file I put in the post was definitely from the Microsoft SDK directory and that the files on my machine in that directory are all dated March 2003 and earlier. I am pretty sure I am using the right age SDK (but I may not be using the SDK for/from the right system... see next paragraph.)

    Lastly, and most importantly, it has come to my attention that the product that I am building is sold only for Server 2000 and Server 2003 and that the previous building of this code base was running on a Server 2003 system. Since I have been trying my builds on an XP machine, I am leaning towards setting up a virtual machine running Server 2003 in which to compile to see if this helps. However, since that will take a while to set up, I was hoping someone out there might have thoughts about whether or not this is likely to help.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  2. Replies: 4
    Last Post: 10-15-2005, 01:13 PM
  3. Full Screen Console
    By St0rmTroop3er in forum C++ Programming
    Replies: 1
    Last Post: 09-26-2005, 09:59 PM
  4. problem with output
    By Garfield in forum C Programming
    Replies: 2
    Last Post: 11-18-2001, 08:34 PM
  5. Levels of Indirection???
    By Garfield in forum C Programming
    Replies: 6
    Last Post: 09-11-2001, 02:06 PM