Like Tree1Likes
  • 1 Post By laserlight

Compile under gcc fails, but VS2010 works

This is a discussion on Compile under gcc fails, but VS2010 works within the C++ Programming forums, part of the General Programming Boards category; I can't figure out why the following code fails to compile under gcc, but works fine when plugged using Microsoft's ...

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    Bay Area, CA
    Posts
    55

    Compile under gcc fails, but VS2010 works

    I can't figure out why the following code fails to compile under gcc, but works fine when plugged using Microsoft's compiler (using VS2010).
    Code:
        TimeCalc time1;
       
        TimeCalc time2("16:28");
        TimeCalc time3("00:16");
       
        TimeCalc time4 = time3;
        TimeCalc time5 = "14:34";
    Under GCC, when it gets to the time5 line, the compile fails with the following error:

    Code:
    ... Lab0.cpp||In function 'int main()':|
    ... Lab0.cpp|250|error: no matching function for call to 'TimeCalc::TimeCalc(TimeCalc)'|
    ... Lab0.cpp|201|note: candidates are: TimeCalc::TimeCalc(TimeCalc&)|
    ... Lab0.cpp|186|note:                 TimeCalc::TimeCalc(const char*)|
    ... Lab0.cpp|112|note:                 TimeCalc::TimeCalc()|
    ||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
    The functions it's suggesting are:

    line 112: the default constructor
    line 186: the constructor taking a string as input
    line 201: the copy constructor

    The program compiles and runs fine under VS2010. When I use the debugger and step through the program, when it gets to time5, it uses the same constructor time2 and time3 use ( TimeCalc(const char* timeIn) ). I don't see why it would be failing under GCC, because it seems like a simple enough statement. I thought time2/time3 and time5 were equivalent ways to construct something?

    Which compiler is wrong or right? Both compilers are running the stock installs, no extra messing around in the options. Is one or the other incomplete? Deviating? I don't have a preference right now of one over the other, I just want to know what the real error is, and what the proper way to handle it is.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    22,157
    Did you declare any constructor for TimeCalc to be explicit? Did you declare the copy constructor for TimeCalc?

    EDIT:
    Heh, I can duplicate your problem on g++ 4.4.4 when I declare the copy constructor to take a non-const reference. Just declare the parameter as a const reference.
    Last edited by laserlight; 01-19-2012 at 04:14 AM.
    Sorin likes this.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2008
    Location
    Bay Area, CA
    Posts
    55
    Quote Originally Posted by laserlight View Post
    Did you declare any constructor for TimeCalc to be explicit? Did you declare the copy constructor for TimeCalc?

    EDIT:
    Heh, I can duplicate your problem on g++ 4.4.4 when I declare the copy constructor to take a non-const reference. Just declare the parameter as a const reference.
    Thanks. I added const to the copy constructor and it works now (it shames me to learn I missed something so elementary), but what was the deal? I stepped through the file with the debugger in fine detail in both CodeBlocks and VS2010, and neither of them went to the copy constructor. In both, it called the constructor that takes a string parameter. So why did the copy constructor issue even make a difference?

    When it comes to differences between gcc and MS, I'd tend to side with gcc because I can't imagine the open source community would deviated from accepted best practices and defined standards (whereas MS often seems to go off and do their own thing). Does VS just ignore the discrepancy between the const call and the non-const declaration?

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,530
    Formally, given a choice of those constructors, the compiler must interpret the code as

    1) invoking the const char * constructor to convert the string to a (temporarily created) TimeCalc
    2) invoking a copy constructor to copy that temporary to another TimeCalc.

    The C++ standard does not allow passing of a temporary by non-const reference. Hence the complaint by the compiler until you make a copy constructor that accepts a const reference.

    Yes, it is true that a compiler is allowed to avoid creating temporaries in some circumstances (if the only way of detecting the temporary is by tracking constructor and destructor calls). But, even if the compiler does avoid creating temporaries, it is still required by the standard diagnose the code as if it is creating those temporaries.

    VS2010 has got it wrong. It is presumably avoiding the creation of the temporaries. But it is also changing how the code is diagnosed.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy in reply to you, it is likely you deserve it. Suck it up, sunshine, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    2,747
    Quote Originally Posted by grumpy View Post
    VS2010 has got it wrong.
    I think it would be more precise to say VS2010 is not following the standards. Getting it wrong implies they did NOT do it on purpose; Microsoft has a past trend of not following the standards on purpose more often than by accident not following them.

    Tim S.
    "Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the Universe is winning." Rick Cook

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    VS2010 has got it wrong. It is presumably avoiding the creation of the temporaries. But it is also changing how the code is diagnosed.
    No, it just allows binding temporaries to non-const references. (And there might not be a way to turn off this compiler extension?)
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    Quote Originally Posted by anon View Post
    No, it just allows binding temporaries to non-const references. (And there might not be a way to turn off this compiler extension?)
    Yes, this is an extension by Microsoft (and if you compile it, you will get warnings about it). It can be turned off in settings. Disable language extensions, it is called. Can't remember exactly where, but it should be easy to find.
    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.

  8. #8
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    There's a constructor that takes a const char *, why does some pointless temporary even come into it?
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  9. #9
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I believe this has already been explained.

    Code:
    TimeCalc time5 = "14:34";
    means almost the same as
    Code:
    TimeCalc time5 = TimeCalc("14:34");
    and
    Code:
    TimeCalc time5(TimeCalc("14:34"));
    except that the first also requires the availability of a non-explicit const char* constructor.

    It's just the rule of the language that the validity of such a construct is checked, even though in 100% of the cases the compiler will just optimize away the unnecessary constructor calls.

    I suppose if you relax the rules to not bother about syntactic validity if something can be optimized away, you'd end up with the compiler's optimizing capabilities and settings determining whether a piece of code is valid or not (and just introduce more unnecessary special cases into the language specification which is complicated as it is).
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  10. #10
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,263
    Quote Originally Posted by anon View Post
    I believe this has already been explained.

    Code:
    TimeCalc time5 = "14:34";
    means almost the same as
    Code:
    TimeCalc time5 = TimeCalc("14:34");
    I thought a declaration/initialization of the form:

    Code:
    Foo x = y;
    Was just another way of writing:

    Code:
    Foo x(y);
    How the hell can I have that wrong?!
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    Registered User
    Join Date
    Jun 2005
    Posts
    6,530
    Apart from the (potential) introduction/elimination of temporaries by the compiler if y is not of type Foo, you were not wrong.

    (Also assuming Foo has a non-explicit copy constructor and conversion constructors).
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy in reply to you, it is likely you deserve it. Suck it up, sunshine, and read this, this, and this before posting again.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Location
    Bay Area, CA
    Posts
    55
    Thanks for the responses guys. These are the kinds of things I like to learn and know about.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. VS2010 C++/CLI Bug
    By nvoigt in forum C++ Programming
    Replies: 3
    Last Post: 10-15-2010, 11:27 AM
  2. This works fine with IP 127.0.0.1 but fails with my REAL IP.
    By azjherben in forum Networking/Device Communication
    Replies: 15
    Last Post: 05-19-2009, 11:28 PM
  3. Compile issue in g++, works fine in VS
    By bean66 in forum C++ Programming
    Replies: 4
    Last Post: 04-20-2009, 10:48 AM
  4. Replies: 5
    Last Post: 04-13-2009, 10:55 AM
  5. RapidMind fails to compile
    By abachler in forum Windows Programming
    Replies: 14
    Last Post: 12-14-2007, 09:01 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21