Conflicting behavior of MS and Borland

Discussion in 'C++' started by Minti, May 20, 2004.

  1. Minti

    Minti Guest

    I tried the following code on Borland C++ complier [ 5.5.1 ] and
    Microsoft VC7.0 both seem to give conflicting results


    void foo(const int& x) { std::cout << "In const foo\n"; }
    void foo(int& x) {std::cout << "In non-const foo\n"; }

    int main(void)
    {
    foo(5);
    int x = 23;
    foo( (const int ) x );
    return 0;
    }

    In case of Borland compiler the result is

    In const foo
    In const foo

    While in case of VC7.0

    In const foo
    In non-const foo

    I could not find much in TC++PL
    --
    Imanpreet Singh Arora
     
    Minti, May 20, 2004
    #1
    1. Advertising

  2. Minti wrote:
    > I tried the following code on Borland C++ complier [ 5.5.1 ] and
    > Microsoft VC7.0 both seem to give conflicting results
    >
    >
    > void foo(const int& x) { std::cout << "In const foo\n"; }
    > void foo(int& x) {std::cout << "In non-const foo\n"; }
    >
    > int main(void)
    > {
    > foo(5);
    > int x = 23;
    > foo( (const int ) x );
    > return 0;
    > }
    >
    > In case of Borland compiler the result is
    >
    > In const foo
    > In const foo


    gcc 3.4.0 and VC7.1 also says this.

    >
    > While in case of VC7.0
    >
    > In const foo
    > In non-const foo


    I suspect it's a bug in VC7.0.

    >
    > I could not find much in TC++PL
     
    Gianni Mariani, May 20, 2004
    #2
    1. Advertising

  3. Gianni Mariani wrote:
    > Minti wrote:
    >
    >> I tried the following code on Borland C++ complier [ 5.5.1 ] and
    >> Microsoft VC7.0 both seem to give conflicting results
    >>
    >>
    >> void foo(const int& x) { std::cout << "In const foo\n"; }
    >> void foo(int& x) {std::cout << "In non-const foo\n"; }
    >>
    >> int main(void)
    >> {
    >> foo(5);
    >> int x = 23;
    >> foo( (const int ) x );
    >> return 0;
    >> }
    >>
    >> In case of Borland compiler the result is
    >>
    >> In const foo
    >> In const foo

    >
    >
    > gcc 3.4.0 and VC7.1 also says this.


    Not the VC7.1 I have. It still says the same as VC7.0. What version of
    the compiler do you have? Mine says

    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077
    for 80x86
    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

    Do I need to update it somehow?

    >
    >>
    >> While in case of VC7.0
    >>
    >> In const foo
    >> In non-const foo

    >
    >
    > I suspect it's a bug in VC7.0.
     
    Victor Bazarov, May 20, 2004
    #3
  4. Minti

    Peter Kragh Guest

    Victor Bazarov wrote:
    > Not the VC7.1 I have. It still says the same as VC7.0. What version of
    > the compiler do you have? Mine says
    >
    > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077
    > for 80x86
    > Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    >
    > Do I need to update it somehow?


    My compiler says:

    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3052 for 80x86
    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

    I.e. it's a bit older than yours. If I turn Microsoft's extension off
    (/Za), I get the expected:

    In const foo
    In const foo

    Just my $0.05

    Br,
    Peter
     
    Peter Kragh, May 20, 2004
    #4
  5. Minti

    Leor Zolman Guest

    On Thu, 20 May 2004 12:45:06 -0400, Victor Bazarov
    <> wrote:

    >Gianni Mariani wrote:
    >> Minti wrote:
    >>
    >>> I tried the following code on Borland C++ complier [ 5.5.1 ] and
    >>> Microsoft VC7.0 both seem to give conflicting results
    >>>
    >>>
    >>> void foo(const int& x) { std::cout << "In const foo\n"; }
    >>> void foo(int& x) {std::cout << "In non-const foo\n"; }
    >>>
    >>> int main(void)
    >>> {
    >>> foo(5);
    >>> int x = 23;
    >>> foo( (const int ) x );
    >>> return 0;
    >>> }
    >>>
    >>> In case of Borland compiler the result is
    >>>
    >>> In const foo
    >>> In const foo

    >>
    >>
    >> gcc 3.4.0 and VC7.1 also says this.

    >
    >Not the VC7.1 I have. It still says the same as VC7.0. What version of
    >the compiler do you have? Mine says
    >
    > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077
    >for 80x86
    > Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    >
    >Do I need to update it somehow?
    >
    >>
    >>>
    >>> While in case of VC7.0
    >>>
    >>> In const foo
    >>> In non-const foo

    >>
    >>
    >> I suspect it's a bug in VC7.0.


    I suspect it is a compatibility "feature" of 7.0 (don't ask me what it is
    supposed to be compatible /with/, since VC6 does it "right" by default...)

    Using both MSVC 7.0 and 7.1 with /Za, I get both const. Without /Za, I get
    the one non-const.

    A revealing diagnostic comes out when you compile it with Comeau, though:

    test.cpp(10): warning: type qualifier is meaningless on cast type
    foo( (const int ) x );

    This makes sense, as casts always produce a temporary that is not
    assignable, I think. So clearly we have a case of the parameter needing to
    be a reference-to-const so that it can bind to a temporary.

    None of this explains why VC7.x does it the other way by default. MSVC
    works in mysterious ways when it comes to its default compatibility mode...
    -leor


    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: download BD Software's free STL Error Message Decryptor at:
    www.bdsoft.com/tools/stlfilt.html
     
    Leor Zolman, May 20, 2004
    #5
  6. Minti

    Minti Guest

    Leor Zolman <> wrote in message news:<>...
    > On Thu, 20 May 2004 12:45:06 -0400, Victor Bazarov
    > <> wrote:
    >
    > >Gianni Mariani wrote:
    > >> Minti wrote:
    > >>
    > >>> I tried the following code on Borland C++ complier [ 5.5.1 ] and
    > >>> Microsoft VC7.0 both seem to give conflicting results
    > >>>
    > >>>
    > >>> void foo(const int& x) { std::cout << "In const foo\n"; }
    > >>> void foo(int& x) {std::cout << "In non-const foo\n"; }
    > >>>
    > >>> int main(void)
    > >>> {
    > >>> foo(5);
    > >>> int x = 23;
    > >>> foo( (const int ) x );
    > >>> return 0;
    > >>> }
    > >>>
    > >>> In case of Borland compiler the result is
    > >>>
    > >>> In const foo
    > >>> In const foo
    > >>
    > >>
    > >> gcc 3.4.0 and VC7.1 also says this.

    > >
    > >Not the VC7.1 I have. It still says the same as VC7.0. What version of
    > >the compiler do you have? Mine says
    > >
    > > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077
    > >for 80x86
    > > Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    > >
    > >Do I need to update it somehow?
    > >
    > >>
    > >>>
    > >>> While in case of VC7.0
    > >>>
    > >>> In const foo
    > >>> In non-const foo
    > >>
    > >>
    > >> I suspect it's a bug in VC7.0.

    >
    > I suspect it is a compatibility "feature" of 7.0 (don't ask me what it is
    > supposed to be compatible /with/, since VC6 does it "right" by default...)
    >
    > Using both MSVC 7.0 and 7.1 with /Za, I get both const. Without /Za, I get
    > the one non-const.
    >
    > A revealing diagnostic comes out when you compile it with Comeau, though:
    >
    > test.cpp(10): warning: type qualifier is meaningless on cast type
    > foo( (const int ) x );
    >
    > This makes sense, as casts always produce a temporary that is not
    > assignable, I think.


    I really don't think that is indeed the case, if the cast can be done
    at compile time
    like in

    const int x = 5.5;

    then there is no need to produce a temporary.

    I am not sure what you mean by "not assignable" do you mean that they
    can't be an lvalue.


    >So clearly we have a case of the parameter needing to
    > be a reference-to-const so that it can bind to a temporary.


    > None of this explains why VC7.x does it the other way by default. MSVC
    > works in mysterious ways when it comes to its default compatibility mode...
    > -leor


    --
    Imanpreet Singh Arora
     
    Minti, May 20, 2004
    #6
  7. Minti

    Leor Zolman Guest

    On 20 May 2004 14:21:46 -0700, (Minti) wrote:

    >> A revealing diagnostic comes out when you compile it with Comeau, though:
    >>
    >> test.cpp(10): warning: type qualifier is meaningless on cast type
    >> foo( (const int ) x );
    >>
    >> This makes sense, as casts always produce a temporary that is not
    >> assignable, I think.

    >
    >I really don't think that is indeed the case, if the cast can be done
    >at compile time
    >like in
    >
    >const int x = 5.5;
    >

    I don't consider that a "cast"; that's just a conversion. By "cast", I mean
    either
    (type) expression
    type (expression)
    or new-style_cast<type>(expression)

    and I'm saying you can't make the result of one of those be the left
    operand of an assignment operator (or ++/--).

    >then there is no need to produce a temporary.


    Right, because it isn't a "cast".

    >
    >I am not sure what you mean by "not assignable" do you mean that they
    >can't be an lvalue.


    That's probably better wording, or "not modifiable" perhaps. I began trying
    to elaborate on this based on what the Standard says; I've been bouncing
    around between 3.10/2, 3.10/6 and writing test programs, and finally
    decided I just don't understand some of the subtleties enough to really
    follow through with an analysis.

    I do, however, have a pet theory as to what the default MSVC 7 behavior is
    doing, even though I haven't a clue why Microsoft would find such behavior
    to be useful. In the strange behavior, the call

    foo ((const int) x);

    results in the function call argument being bound to a reference to
    non-const (the function parameter). Here's what section 3.10/6 has to say
    about the result of casts:

    "An expression which holds a temporary object resulting from a cast to
    a nonreference type is an rvalue (this includes the explicit creation
    of an object using functional notation (5.2.3))."

    My suspicion is that the strange behavior is ignoring this rule, and
    retaining all the lvalue-ness of the cast's operand. Thus it behaves as we
    see when the operand is an lvalue, but not when it is a constant. Consider
    this expansion of the original example:

    #include <iostream>

    void foo(int& x) {std::cout << "In non-const foo\n"; }
    void foo(const int& x) { std::cout << "In const foo\n"; }

    int main(void)
    {
    int x = 23;

    foo(5);
    foo(x);
    foo( (const int ) x );
    foo( (const int ) 5 );

    return 0;
    }

    The output is:

    In const foo
    In non-const foo
    In non-const foo
    In const foo

    The third one is the strange one, and can be explained by imagining that
    the cast isn't actually producing a "new" temporary value, but rather is
    passing the original operand x "as if" it had the desired type. The last
    example shows that if you start with a constant (5), it doesn't magically
    turn into an lvalue (which is a good thing.)

    Another shot in the dark: perhaps Microsoft is interpreting 3.10/6's use of
    the term "nonreference" to mean that, when the argument can be bound to a
    (non-const) reference in the function call, the result of the cast is no
    longer a "nonreference type" and thus exempt from the requirements of being
    an rvalue. But if /Za is used, it battens down the hatches. I just have no
    idea.

    For what it's worth.
    -leor




    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: download BD Software's free STL Error Message Decryptor at:
    www.bdsoft.com/tools/stlfilt.html
     
    Leor Zolman, May 21, 2004
    #7
  8. Victor Bazarov wrote:
    > Gianni Mariani wrote:
    >
    >> Minti wrote:
    >>
    >>> I tried the following code on Borland C++ complier [ 5.5.1 ] and
    >>> Microsoft VC7.0 both seem to give conflicting results
    >>>
    >>>
    >>> void foo(const int& x) { std::cout << "In const foo\n"; }
    >>> void foo(int& x) {std::cout << "In non-const foo\n"; }
    >>>
    >>> int main(void)
    >>> {
    >>> foo(5);
    >>> int x = 23;
    >>> foo( (const int ) x );
    >>> return 0;
    >>> }
    >>>
    >>> In case of Borland compiler the result is
    >>>
    >>> In const foo
    >>> In const foo

    >>
    >>
    >>
    >> gcc 3.4.0 and VC7.1 also says this.

    >
    >
    > Not the VC7.1 I have. It still says the same as VC7.0. What version of
    > the compiler do you have? Mine says
    >
    > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077
    > for 80x86
    > Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    >
    > Do I need to update it somehow?


    Nope - It was my mistake ... Getting a bit punchy at 9:00AM !

    >
    >>
    >>>
    >>> While in case of VC7.0
    >>>
    >>> In const foo
    >>> In non-const foo

    >>
    >>
    >>
    >> I suspect it's a bug in VC7.0.
     
    Gianni Mariani, May 21, 2004
    #8
  9. "Gianni Mariani" <> wrote...
    > Victor Bazarov wrote:
    > > Gianni Mariani wrote:
    > >
    > >> Minti wrote:
    > >>
    > >>> I tried the following code on Borland C++ complier [ 5.5.1 ] and
    > >>> Microsoft VC7.0 both seem to give conflicting results
    > >>>
    > >>>
    > >>> void foo(const int& x) { std::cout << "In const foo\n"; }
    > >>> void foo(int& x) {std::cout << "In non-const foo\n"; }
    > >>>
    > >>> int main(void)
    > >>> {
    > >>> foo(5);
    > >>> int x = 23;
    > >>> foo( (const int ) x );
    > >>> return 0;
    > >>> }
    > >>>
    > >>> In case of Borland compiler the result is
    > >>>
    > >>> In const foo
    > >>> In const foo
    > >>
    > >>
    > >>
    > >> gcc 3.4.0 and VC7.1 also says this.

    > >
    > >
    > > Not the VC7.1 I have. It still says the same as VC7.0. What version of
    > > the compiler do you have? Mine says
    > >
    > > Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077
    > > for 80x86
    > > Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    > >
    > > Do I need to update it somehow?

    >
    > Nope - It was my mistake ... Getting a bit punchy at 9:00AM !


    Gianni, you were correct, the others suggested that "language extensions"
    were turned on, and they were correct. I turned language extensions off
    and got the behaviour you described. I wonder how long MSoft is going
    to keep "extensions" _on_ by default...

    Thanks to all for corrections.

    V
     
    Victor Bazarov, May 21, 2004
    #9
  10. Leor Zolman wrote:
    > On Thu, 20 May 2004 12:45:06 -0400, Victor Bazarov
    > <> wrote:
    > >
    >>Gianni Mariani wrote:
    >>
    >>>Minti wrote:
    >>>
    >>>>I tried the following code on Borland C++ complier [ 5.5.1 ] and
    >>>>Microsoft VC7.0 both seem to give conflicting results
    >>>>
    >>>>
    >>>>void foo(const int& x) { std::cout << "In const foo\n"; }
    >>>>void foo(int& x) {std::cout << "In non-const foo\n"; }
    >>>>
    >>>>int main(void)
    >>>>{
    >>>> foo(5);
    >>>> int x = 23;
    >>>> foo( (const int ) x );
    >>>> return 0;
    >>>>}
    >>>>
    >>>>In case of Borland compiler the result is
    >>>>
    >>>>In const foo
    >>>>In const foo
    >>>

    [Snip]

    >
    > I suspect it is a compatibility "feature" of 7.0 (don't ask me what it is
    > supposed to be compatible /with/, since VC6 does it "right" by default...)
    >
    > Using both MSVC 7.0 and 7.1 with /Za, I get both const. Without /Za, I get
    > the one non-const.
    >
    > A revealing diagnostic comes out when you compile it with Comeau, though:
    >
    > test.cpp(10): warning: type qualifier is meaningless on cast type
    > foo( (const int ) x );
    >
    > This makes sense, as casts always produce a temporary that is not
    > assignable, I think. So clearly we have a case of the parameter needing to
    > be a reference-to-const so that it can bind to a temporary.
    >
    > None of this explains why VC7.x does it the other way by default. MSVC
    > works in mysterious ways when it comes to its default compatibility mode...
    > -leor
    >
    >


    I dont know if this sheds any light on why MS would have such a language
    extension, but you can use a similar cast on an lvalue in VC7.1 with
    language extensions on.

    const int c = 4;
    int n = 5;
    volatile int v = 6;

    (const int)n = 6; // Fine in VC 7.1 with extensions
    (int)v = 3; // Fine in VC 7.1 with extensions

    (int)c = 3; // illegal
    (unsigned int)n = 7; // illegal


    But still ... why?

    - Jake Montgomery
     
    Jake Montgomery, May 22, 2004
    #10
  11. Minti

    Leor Zolman Guest

    On Fri, 21 May 2004 23:44:08 GMT, Jake Montgomery
    <> wrote:

    >
    >I dont know if this sheds any light on why MS would have such a language
    >extension, but you can use a similar cast on an lvalue in VC7.1 with
    >language extensions on.
    >
    >const int c = 4;
    >int n = 5;
    >volatile int v = 6;
    >
    >(const int)n = 6; // Fine in VC 7.1 with extensions
    >(int)v = 3; // Fine in VC 7.1 with extensions
    >
    >(int)c = 3; // illegal
    >(unsigned int)n = 7; // illegal
    >


    Yup, that's consistent with my "pet theory" in my reply to Minti above:
    this language extension allows a cast to serve as a type modifier on the
    actual lvalue operand, rather than necessarily resulting in an rvalue
    temporary as the Standard dictates.

    >
    >But still ... why?


    Indeed. The kicker, to me, is that MSVC 6 does not seem to exhibit this
    extension (at least not by default).
    -leor

    >
    > - Jake Montgomery


    --
    Leor Zolman --- BD Software --- www.bdsoft.com
    On-Site Training in C/C++, Java, Perl and Unix
    C++ users: download BD Software's free STL Error Message Decryptor at:
    www.bdsoft.com/tools/stlfilt.html
     
    Leor Zolman, May 22, 2004
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Joe
    Replies:
    1
    Views:
    420
  2. Ben Engbers
    Replies:
    0
    Views:
    496
    Ben Engbers
    Feb 7, 2007
  3. Lathe_Biosas
    Replies:
    8
    Views:
    843
    Joe Wright
    Sep 2, 2005
  4. Alf P. Steinbach
    Replies:
    1
    Views:
    324
    Adam Aulick
    May 26, 2006
  5. Replies:
    1
    Views:
    1,126
    SuperKoko
    Oct 2, 2006
Loading...

Share This Page