Thread: Compile under gcc fails, but VS2010 works

  1. #1
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70

    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
    28,413
    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.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    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,815
    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 or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    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.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  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
    Location
    Inside my computer
    Posts
    24,654
    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
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    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,815
    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 or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  12. #12
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    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, 10: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, 10:28 PM
  3. Compile issue in g++, works fine in VS
    By bean66 in forum C++ Programming
    Replies: 4
    Last Post: 04-20-2009, 09:48 AM
  4. Replies: 5
    Last Post: 04-13-2009, 09:55 AM
  5. RapidMind fails to compile
    By abachler in forum Windows Programming
    Replies: 14
    Last Post: 12-14-2007, 09:01 AM