strange runtime behaviour with gcc

Discussion in 'C++' started by Levent, Jun 1, 2005.

  1. Levent

    Levent Guest

    Hi,

    When compiled with gcc 3.3.3 and lower on various systems (tried cygwin,
    linux, aix) the following code behaves strangely:

    #include <iostream>

    class Foo {
    public:
    typedef int subs[3];
    void callme(subs s)
    {
    std::cout << s[2] << std::endl;
    }
    };

    template<class foo_type>
    class Bar
    {
    public:
    void callme(typename foo_type::subs s)
    {
    std::cout << s[2] << std::endl;
    }
    };

    int main()
    {
    int sz[]={10,20,30};
    Foo f;
    f.callme(sz); // should print 30 and it does
    Bar<Foo> b;
    b.callme(sz); // should print 30 but it does not with gcc
    return 0;
    }

    The problem is that `Bar<Foo>::callme' somehow accesses uninitized space
    in memory instead of the one sz[] points to. This is not the case with
    any other compiler I had access to (visual c++ 7.1, visualage 6, intel
    7 and 8).

    Does the above code have semantic problems, or is this just a gcc-bug
    (in which case I apologize for this gcc specific and thus off-topic(ish)
    thread)?

    - L.
    Levent, Jun 1, 2005
    #1
    1. Advertising

  2. Levent

    Teddy Guest

    the code works well on my gcc 3.3.3 after i made the modification
    below:
    class Foo {
    public:
    typedef int* subs; //modification here
    void callme(subs s)
    {
    std::cout << s[2] << std::endl;
    }
    };

    interesting , and i want to why
    Teddy, Jun 1, 2005
    #2
    1. Advertising

  3. Levent

    Peter Julian Guest

    "Levent" <> wrote in message
    news:d7k99h$391$...
    > Hi,
    >
    > When compiled with gcc 3.3.3 and lower on various systems (tried cygwin,
    > linux, aix) the following code behaves strangely:


    Well, then give gcc the prize becuse the other compilers failed the task.

    >
    > #include <iostream>
    >
    > class Foo {
    > public:
    > typedef int subs[3];


    undefined behaviour, an array object is not an integer nor can it ever be.
    typedef is meant to create a new type definition, not to act like a pointee
    converter.

    <snip>

    > int main()
    > {
    > int sz[]={10,20,30};


    Why aren't you encapsulating the array container? Why bother write the
    classes Foo and Bar otherwise?

    > Foo f;
    > f.callme(sz); // should print 30 and it does
    > Bar<Foo> b;
    > b.callme(sz); // should print 30 but it does not with gcc
    > return 0;
    > }
    >
    > The problem is that `Bar<Foo>::callme' somehow accesses uninitized space
    > in memory instead of the one sz[] points to.


    Because subs is passed as an integer to Bar<Foo>callme's parameter, subs is
    not an array. A compiler that allows ...

    typedef int subs[3];

    .... is allowing undefined behaviour. C++ implies strict type checking, not a
    particular compiler's version of type redefinitions.

    Try the code below in all compilers mentioned above:
    Note that an array is not the appropriate container here. A vector would
    have been more usefull. Foo's constructor initializes the array's elements.
    The member functions callme() only need a reference to the container's
    index.

    The array is a private member of the Foo type, and the Bar type is
    *composed* of a templated member that must support the callme() member
    function.

    #include <iostream>

    class Foo
    {
    int subs[3];
    public:
    Foo()
    {
    std::cout << "Foo ctor invoked\n";
    subs[0] = 10;
    subs[1] = 20;
    subs[2] = 30;
    }
    void callme(const int& i) const
    {
    std::cout << subs << std::endl;
    }
    };

    template<class foo_type>
    class Bar
    {
    foo_type t;
    public:
    Bar() : t() { std::cout << "Bar ctor invoked\n"; }
    void callme(const int& i) const
    {
    t.callme(i);
    }
    };

    int main()
    {
    Foo f;
    f.callme(2); // should print 30

    Bar<Foo> b;
    b.callme(2); // should print 30

    return 0;
    }

    /* output:

    Foo ctor invoked
    30
    Foo ctor invoked
    Bar ctor invoked
    30

    */

    A vector is a much better choice than an array. Also, if Foo and Bar are
    meant to have an "is_a" relationship (a Bar is_a Foo, a Car is_a Vehicle, a
    Circle is_a shape), then you should have Bar inherit from Foo instead.
    Peter Julian, Jun 1, 2005
    #3
  4. Levent

    Old Wolf Guest

    Peter Julian wrote:
    >
    > A compiler that allows ...
    >
    > typedef int subs[3];
    >
    > ... is allowing undefined behaviour.


    Please review your C++ textbook. That code is correct and
    declares that 'subs' is an alias for an array of 3 ints.
    Old Wolf, Jun 2, 2005
    #4
  5. Levent

    Pete Becker Guest

    Peter Julian wrote:
    > "Levent" <> wrote in message
    > news:d7k99h$391$...
    >
    >>Hi,
    >>
    >>When compiled with gcc 3.3.3 and lower on various systems (tried cygwin,
    >>linux, aix) the following code behaves strangely:

    >
    >
    > Well, then give gcc the prize becuse the other compilers failed the task.
    >


    If you were right that the behavior of this code is undefined, it
    wouldn't follow that any compiler failed in any way. Undefined behavior
    is simply undefined. The language definition does not require any
    particular behavior, so anything a compiler does is okay.

    >
    >>#include <iostream>
    >>
    >>class Foo {
    >>public:
    >> typedef int subs[3];

    >
    >
    > undefined behaviour, an array object is not an integer nor can it ever be.
    > typedef is meant to create a new type definition, not to act like a pointee
    > converter.
    >


    The typedef says that 'subs' is an array of 3 ints.

    --

    Pete Becker
    Dinkumware, Ltd. (http://www.dinkumware.com)
    Pete Becker, Jun 2, 2005
    #5
  6. Levent

    Levent Guest

    Levent, Jun 3, 2005
    #6
    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. Replies:
    8
    Views:
    428
  2. Kevin P. Fleming

    C99 structure initialization in gcc-2.95.3 vs gcc-3.3.1

    Kevin P. Fleming, Nov 6, 2003, in forum: C Programming
    Replies:
    2
    Views:
    644
    Kevin P. Fleming
    Nov 6, 2003
  3. Replies:
    5
    Views:
    358
    Nathan Addy
    Sep 17, 2005
  4. ashnin

    GCC 3.4.3 and GCC 4.1.2

    ashnin, Jul 7, 2008, in forum: C++
    Replies:
    1
    Views:
    519
    Michael DOUBEZ
    Jul 7, 2008
  5. kas
    Replies:
    1
    Views:
    315
    red floyd
    Apr 22, 2010
Loading...

Share This Page