Issues with your account? Bug us in the Discord!

Calling all advanced coders

BekennBekenn Sinclair's Duck
There we go, that "advanced" word ought to make everyone look....

I'm having a problem compiling code that was not (repeat, [i]not[/i]) written by me. This code is built to a static library (.lib) file, and utilizes the std::list class. Specifically, one of the headers has the line [code]#include &lt list&gt // *[/code] and an object of that class is used as a member variable for a different class defined in the header.

I'll probably have to clarify that later, but on to the weirdness:

Attempting to build the library works just fine -- provided that you're making a release build. Attempting to make a debug build results in (of all things) a syntax error.

You'd think that the code is either syntactically correct or incorrect; changing the build type shouldn't change that.

But wait, there's more! The syntax error occurs [i]not[/i] within the library I'm trying to build, but [i]within [b]list[/b] itself[/i]. That is, the syntax error shows up on line 864 of the header file needed to use std::list!

And it's just a simple syntax error! No other errors are even reported! And this is a file that comes with the IDE (in this case, Visual Studio .NET).

Given the circumstances, I find it impossible to believe that there's anything wrong with the [b]list[/b] header file, and I've checked the library's code for #if statements involving the _DEBUG or NDEBUG symbols. I've even tried changing the debug build settings to more closely match the retail build settings, and so far nothing's had any effect.

Any ideas?

* Without the space. For some reason, either vBulletin or Firefox doesn't change & l t to &lt if you just run it together with the word ahead of it.
«1

Comments

  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    Firstly, that's probably vbulliten changing stuff, due to the way it stores things in the database.

    Now on to your main problem: I have also encountered this problem in the past. Unfortunately, I can't remember how I fixed it. :) I shall meditate on it tonight and get back to you next access time.
  • BekennBekenn Sinclair's Duck
    Thanks!

    All you others: don't let that keep you from replying!
  • Remember that debug builds in VStudio, by default, override "new" and other "standard" C syntax.

    Perhaps your memory management is getting out of sync? If one set of code defines memory management routines one way, and another defines them another way, the link and/or compile may get confused.

    Release builds generally do much less of this, which would explain the release compile working fine.

    I don't know that this is your problem, but it is one of the things I look at in similar circumstances.

    -- john :shadow1:
  • JackNJackN <font color=#99FF99>Lightwave Alien</font>
    Re: Calling all advanced coders

    [QUOTE][i]Originally posted by Bekenn [/i]
    [B]I'm having a problem... [/B][/QUOTE]

    I got lost on the "I'm having a problem..." part...

    :p
  • BekennBekenn Sinclair's Duck
    John, I think you're on to something; the syntax error occurs in a [b]new[/b] statement. Specifically:
    [code]new ((void *)_Pnode) _Node(_Next, _Prev, _Val);
    [/code]

    It craps out on one of the opening parentheses in that line.

    So, what do I have to change?
  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    Well that's where things get hard. The redefined new operator doesn't just allocate memory, it also does things like fill it all with 0xCC (so when you look at it during debugging you can see where it's been written) and adds bounds checking, stuff like that. Probably what's happening is a conflict between the syntax in the list header file and the syntax in the function that implements new.
  • What do you do? RTFM! :D Kidding.

    I don't remember what it is, but there is a define or something to tell VS not to do that. You may have to set a define in your project settings (with the other defines like _NDEBUG) so it affects everything or set it in a header before including windows.h or something like that. Like I said, I can't remember...

    It may also be one of those magical project settings. Which version of VS are you using? I have .net '02 and '03 at work, but no access anymore to VC6.

    I'm also not thrilled by the initial void* in there, but it is probably fine. Template and meta-template programming makes me dizzy.

    The _Node type needs to have a three argument constructor, but I would have expected a different error than syntax.

    Have you tried re-arranging the order of the headers of the library vs. your app?
    Are you using pre-compiled headers?
  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    Precompiled headers could certainly cause a problem... they may need to be recompiled again or something.
  • BekennBekenn Sinclair's Duck
    [QUOTE][i]Originally posted by John Walker [/i]
    [B]What do you do? RTFM! :D Kidding.[/B][/QUOTE]

    Heh. Kidding or not, that's exactly what I spent many hours doing before resorting to actually (gasp) asking for help.

    [QUOTE][B]I don't remember what it is, but there is a define or something to tell VS not to do that. You may have to set a define in your project settings (with the other defines like _NDEBUG) so it affects everything or set it in a header before including windows.h or something like that. Like I said, I can't remember... [/B][/QUOTE]

    Well, that's something to look for, at least.

    [QUOTE][B]It may also be one of those magical project settings. Which version of VS are you using? I have .net '02 and '03 at work, but no access anymore to VC6.[/B][/QUOTE]

    VS.Net 2002. Y'know, the version that won't work with 2003's project files (grr).

    [QUOTE][B]I'm also not thrilled by the initial void* in there, but it is probably fine. [/B][/QUOTE]

    I look at it this way: it's in the header. It's a standard header, and it came with Visual Studio. Therefore, it must be okay.

    ...Okay, so I'm not actually quite that trusting, so I did some research. Turns out that the syntax associated with the [b]new[/b] operator allows you to pass an argument if you're using an overloaded version of [b]new[/b]. That argument comes before the type name. My guess as to what's happening here is that the [b]_Node[/b] variant of the [b]list[/b] class defines its own [b]new[/b] operator, which has a [b]void *[/b] argument.

    Notice that the statement above is completely isolated; it isn't [code]x = new ((void *)_Pnode) _Node(_Next, _Prev, _Val);[/code] but rather just plain [code]new ((void *)_Pnode) _Node(_Next, _Prev, _Val);[/code]

    My guess is that the overloaded [b]new[/b] operator uses that parameter to store the location of the new [b]_Node[/b]; hence the name [b]_Pnode[/b].

    [QUOTE][B]Template and meta-template programming makes me dizzy.[/B][/QUOTE]

    I'm exactly the same way. I hate, hate, hate template classes.

    [QUOTE][B]The _Node type needs to have a three argument constructor, but I would have expected a different error than syntax. [/B][/QUOTE]

    Yeah, that's exactly what got me. Syntax?? Shouldn't the interface for the [b]new[/b] operator be the same regardless of how it's implemented?

    [QUOTE][B]Have you tried re-arranging the order of the headers of the library vs. your app?[/B][/QUOTE]

    Yup. No luck so far.

    [QUOTE][B]Are you using pre-compiled headers? [/B][/QUOTE]

    Yes, but every time I change the build settings, that gets recompiled anyway.
  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    Template classes can be very nice when used simply and clearly. When they're used convolutedly and complexly like they are with the standard library... ug.
  • BekennBekenn Sinclair's Duck
    Well, I've checked around, and haven't been able to find anything at all. Need more ideas....

    Edit: I just tried changing the runtime library that it uses from multi-threaded debug to multi-threaded. Even that doesn't fix the syntax error, so it has to be something else. I'm at a complete loss here.
  • JackNJackN <font color=#99FF99>Lightwave Alien</font>
    [QUOTE][i]Originally posted by Bekenn [/i]
    [B]John, I think you're on to something; the syntax error occurs in a [b]new[/b] statement. Specifically:
    [code]new ((void *)_Pnode) _Node(_Next, _Prev, _Val);
    [/code]

    It craps out on one of the opening parentheses in that line.

    So, what do I have to change? [/B][/QUOTE]

    I know this may seem stupid... In java scripting I sometimes have to wrap everything in a new set of parenthesis.

    When I look at your code below here...

    [code]new ((void *)_Pnode) _Node(_Next, _Prev, _Val);
    [/code]

    I am tempted to suggest changing it to this:

    [code]new (((void *)_Pnode) _Node(_Next, _Prev, _Val));
    [/code]

    That new call might only be seeing the first set( (void *)_Pnode) and truncating the remainder?

    If this is totally stupid then forgive me, it just seems to me that a syntax error might be pointing to some kind of typo like this. I get this a lot in Excel formulas and in JavaScripting...
  • BekennBekenn Sinclair's Duck
    No worries, Jack. The more ideas I see, the more one of them is likely to be right.

    As to why that won't work:

    It changes everything after the [b]new[/b] keyword into a single expression. Something that isn't immediately obvious, given that I only provided one line of code, is that [b]_Pnode[/b] is a variable, whereas [b]_Node[/b] is a class type (with [b]_Next[/b], [b]_Prev[/b], and [b]_Val[/b] being arguments for [b]_Node[/b]'s constructor). The syntax of [b]new[/b] works like this:

    [b]new[/b] [i][placement] type-name [new-initializer][/i]

    Stuff in brackets is optional.

    The [i]placement[/i] element is a spot to put arguments if you make your own version of [b]new[/b].

    [i]type-name[/i] is where you specify what kind of thing you're creating.

    [i]new-initializer[/i] is a spot where you can put an initial value for whatever you're creating.

    In this case, [b]((void *)_Pnode)[/b] is the [i]placement[/i] and [b]_Node(_Next, _Prev, _Val)[/b] is the [i]type-name[/i]. Throwing parentheses around that would make the compiler try to consolidate both items into a single element.

    Additionally, if it actually were a problem with syntax, the compiler would complain when trying to make a release build. The code itself is not wrong; it has to be something else.
  • From what you said above, I'm wondering if the redefined/overloaded new from list is conflicting with the MS debug defined version of new...
  • BekennBekenn Sinclair's Duck
    Agreed, but even if it is -- what then? Change the header? That seems wrong somehow.

    Anyway, I just did some extensive testing with the build options (I created a new configuration called "test", inheriting all options from "release", and changed the options to match "debug" one by one), and I've discovered that it's a combination of two build options at fault here.

    The library fails to build if either or both of the two following conditions are true:

    1: The _DEBUG symbol is defined
    2: A debug version of the run-time library is selected (multi-threaded debug, single-threaded debug, multi-threaded DLL debug)

    Edit: The other thing that gets me is that I can't find any reference to any similar problems on Google. So there can't be anything wrong with the [b]list[/b] header.
  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    Do a find in files and search through the library's source for what they wrap in #defines with the _DEBUG define. See if they have their own version of new in there for debugging or something that could be conflicting with the one provided by VS and used by stdlib.
  • BekennBekenn Sinclair's Duck
    Couldn't find any [b]new[/b] overloading in the library I'm trying to build, but I did turn up an interesting file called "fixdelete.h". It's short, so a complete listing follows:

    [code]#ifndef __FixDelete_h__
    #define __FixDelete_h__

    #if _MSC_VER > 1000
    #pragma once
    #endif

    /////////////////////////////////////////////////////////////////////////////
    // This is 'borrowed' from the CRT to ensure that delete is as we expect. //
    // //
    // The problem arises when using STL, which appears to me as a bug in its //
    // implementation of the global operator delete. The STL implementation //
    // (from &lt new&gt simply calls free, with no regard to how the block was //
    // allocated. Under _DEBUG builds, this causes an assert failure since //
    // some blocks are allocated with the _CLIENT_BLOCK flag, and free always //
    // checks for the _NORMAL_BLOCK flag. //
    // //
    // The following code correctly passes that flag to the _free_dbg function //
    // so that the assert never fails. The code has been written-out since, by //
    // including the STL file &lt new&gt, the CRT implementation is hidden from the //
    // linker. As far as I know, there is no simple way to ignore the source //
    // code implementation (from &lt new&gt) and force the linker to use the CRT //
    // implementation. //
    //
    #ifdef _DEBUG //
    // Structure definition (abridged) from &lt crt/src/dbgint.h&gt //
    #ifndef nNoMansLandSize //
    #define nNoMansLandSize 4 //
    typedef struct _CrtMemBlockHeader //
    { //
    struct _CrtMemBlockHeader * pBlockHeaderNext; //
    struct _CrtMemBlockHeader * pBlockHeaderPrev; //
    char * szFileName; //
    int nLine; //
    size_t nDataSize; //
    int nBlockUse; //
    long lRequest; //
    unsigned char gap[nNoMansLandSize]; //
    } _CrtMemBlockHeader; //
    #endif // !nNoMansLandSize //
    //
    // Function definition (abridged) from &lt crt/src/dbgdel.cpp&gt //
    inline void __cdecl operator delete(void *pUserData) //
    { //
    if (pUserData == NULL) //
    return; //
    _CrtMemBlockHeader* pHead = (((_CrtMemBlockHeader *)pUserData)-1); //
    _free_dbg(pUserData, pHead->nBlockUse); //
    } //
    #endif // _DEBUG //
    //
    /////////////////////////////////////////////////////////////////////////////

    #endif // !__FixDelete_h__
    [/code]

    Gotta look into this [b]new[/b] header now....

    Edit: the [b]new[/b] header simply seems to confirm my theory that _Pnode is a pointer to the new _Node. I haven't seen anything that cares whether or not it's a debug build.
  • JackNJackN <font color=#99FF99>Lightwave Alien</font>
    [QUOTE][i]Originally posted by Bekenn [/i]
    [B]No worries, Jack. The more ideas I see, the more one of them is likely to be right.

    ...

    Additionally, if it actually were a problem with syntax, the compiler would complain when trying to make a release build. [/B][/QUOTE]

    :cool:

    Well I knew it was a longshot... :D

    It's kinda interesting how some things look the same no matter what programming language someone uses...

    I just don't know enough about C to be of any help... ;)

    Just out of curiosity, what is "void *", and or what does it do? void everything? or multiply something?

    operator vs. wildcard...

    Looking at some of the other code above, I also have a question as to why (void *_Pnode) wouldn't work
    in place of ((void *)_Pnode) ?

    I ask this because of how the end of this line looks in the code above:

    inline void __cdecl operator delete[b](void *pUserData) [/b]
  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    It looks very similar in this case, Jack, because javascript uses java syntax, which is mostly based on C syntax. :)

    void * makes a new pointer of type void (ie, no type). The reason the parantheses are needed in your other point are because it is casting _Pnode to the type void*. Without them, it would be declaring _Pnode as a new void*, which would be a problem both in terms of syntax and the fact that _Pnode already exists. You get messy things like this in a language that is designed to be infinitely flexible like C or C++. That's why infinite flexibility isn't always a good thing. :)
  • BekennBekenn Sinclair's Duck
    Jack: I don't know how familiar you are with the concept of pointers in general, so here's the basic idea:

    Pointers are variables that tell you where in memory a given value is stored. They are usually used to address large structures, and to allow values to persist across boundaries of scope, when ordinary variables would normally be destroyed or inaccessible.

    A lot of people find pointers to be very confusing, and in fact one of Java's selling points is its claim that it has no pointers. (Although, in point of fact, practically everything in Java actually is a pointer -- the language just handles the details behind the scenes, and it's the near-complete lack of non-pointers that vastly simplifies the syntax.)

    So, is that muddied up enough for you?
  • JackNJackN <font color=#99FF99>Lightwave Alien</font>
    yep and yep...

    I've much to learn (or in this case, un-learn... :eek: )

    :p :D

    Well I wish I could help Bekenn...

    I owe you, and several others out here on thes forums...

    I'll eventually find a way to return the favors...

    :)
  • PJHPJH The Lovely Thing
    All this reminds me why I hated using pointers back in the days when I was still doing some coding stuff. Pointers really can be confusing indeed.

    Btw, you guys forgot to tell to Jack, that pointers are usually used to handle classes (those large structures Bekenn mentioned).

    [PJH's reminiscent mode]
    Pointers to pointers... ughhhh..... *shivers* Heeeeellpppppp!! Wake me up from this nightmare!!
    [/PJH's reminiscent mode]

    :eek:

    Btw, don't be so surprised if there was an error in some header file. That's known to have happened.

    - PJH
  • BekennBekenn Sinclair's Duck
    [QUOTE][i]Originally posted by PJH [/i]
    [B][PJH's reminiscent mode]
    Pointers to pointers... ughhhh..... *shivers* Heeeeellpppppp!! Wake me up from this nightmare!!
    [/PJH's reminiscent mode][/B][/QUOTE]

    Those were always fun; got to deal with them a lot back when I was still coding a cell phone game.

    [QUOTE][B]Btw, don't be so surprised if there was an error in some header file. That's known to have happened.[/B][/QUOTE]

    Yeah, but VS.Net 2002 has been out for some time now. If there were a problem with the headers, it would have come to light. I haven't found any instance of anyone having the same problem in all my Google searches to date.
  • PJHPJH The Lovely Thing
    [QUOTE][i]Originally posted by Bekenn [/i]
    [B]
    Yeah, but VS.Net 2002 has been out for some time now. If there were a problem with the headers, it would have come to light. I haven't found any instance of anyone having the same problem in all my Google searches to date. [/B][/QUOTE]

    Yeah I suppose so.

    - PJH
  • This thread has reminded me of why I gave up on programming and started writing. :D
  • BekennBekenn Sinclair's Duck
    Well, in the vast majority of cases, you don't have problems quite like this one....
  • BigglesBiggles <font color=#AAFFAA>The Man Without a Face</font>
    I like pointers. :) You can right such amazingly confusing code with them. Still no luck with the problem? Unfortunately my mediation in a 500 year old zen temple didn't help me think of anything other than "try another STL library"
  • BekennBekenn Sinclair's Duck
    [QUOTE][i]Originally posted by Biggles [/i]
    [B]I like pointers. :) You can [i]write[/i] such amazingly confusing code with them. [/B][/QUOTE]

    Agreed!

    [QUOTE][B]Still no luck with the problem? Unfortunately my [i]meditation[/i] in a 500 year old zen temple didn't help me think of anything other than "try another STL library" [/B][/QUOTE]

    Heh. Nope, no luck; I've put that particular module on the backburner for now. There's lots of other code in this project that needs compiling; lately, I've been having to read up on MIDL for one portion. I hadn't ever come across it before.

    In case you're wondering, I'm trying to compile the [url=http://www.freeallegiance.org/]Allegiance[/url] [url=http://dev.alleg.net/]source code[/url] that Microsoft released a while back. There's a whole slew of makefiles scattered throughout the archive that the Allegiance folks recommmend using, but I like having everything arranged neatly in an IDE. (And, no, the makefiles were no help in solving this particular problem.)
  • [QUOTE] There's a whole slew of makefiles scattered throughout the archive that the Allegiance folks recommmend using, but I like having everything arranged neatly in an IDE. (And, no, the makefiles were no help in solving this particular problem.)[/QUOTE]

    This smacks of an include order or independent compile with different options...

    I took a quick look and I couldn't find the "don't use the new override" option I spoke of. I'm sorry that I don't have any "real" time to work on it for you. :( (Just ask Biggles about the B5 AI doc) :(

    [COLOR=skyblue]Pointers:[/COLOR]
    I have some bad news for those of you who dislike pointers. If you want to be a really good C/C++ programmer, you need to master the use of pointers, references, double pointers, pointers as parameters, pointer manipulation and incrementing, etc. There is no [url=http://catb.org/~esr/jargon/html/E/elite.html]'leet[/url] [url=http://catb.org/~esr/jargon/html/W/wizard.html]wizard[/url]ly [url=http://catb.org/~esr/jargon/html/H/heavy-wizardry.html]mojo[/url] without pointer mastery.

    The only way to avoid pointers is to stick to C#/Java/[url=www.ruby-lang.org]Ruby[/url]/Lisp/Scheme/Python/PHP/Perl/ and other high-level languages (HLL). There is nothing wrong with that, deveopments speed is [b]much[/b] faster with HLL's, and you can spend your memory on powerful API tricks and constructs rather than remembering the format for sending a function pointer, but low-level, highly optimized systems (rendering pipelines, heavy math/physics systems, databases, etc.) are still and for the forseeable future will be) written in C & C++.

    Note: I do personal projects, even graphical ones in Ruby or C#. I care about getting stuff done, not performance; it's not like I'm writing a game engine or something.
  • JackNJackN <font color=#99FF99>Lightwave Alien</font>
    [QUOTE][i]Originally posted by John Walker [/i]
    [B]... it's not like I'm writing a game engine or something. [/B][/QUOTE]

    Well what the hell are you doing all day then?!? :D :p j/k

    I can write decent stuff in HTML, JavaScript, PHP, Perl, and Cold Fusion and with MySQL and ODBC databases. Beyond those.. My head hurts...

    Oh and give me a C-64, and I can whip up some mean BASIC with pokes and peeks... :p
Sign In or Register to comment.