error: parameter may not have variably modified type

Discussion in 'C++' started by Helmut Jarausch, Oct 21, 2009.

  1. Hi,

    I have got the following error message which I don't understand

    branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool, size_type, const Float&)':
    branch_E.cc:48882: error: parameter may not have variably modified type 'space [(((long unsigned int)(((long int)i) +
    -0x00000000000000001)) + 1)]'


    space V = u.get_space();
    ......
    // The (preprocessed) failing source line is
    Form proj (space(V), V_new_i, "mass");


    class Form has the corresponding constructor

    Form (const space& X, const space& Y, const std::string& op_name,
    bool locked_boundaries=false);

    and

    class space : public smart_pointer<spacerep> {
    space(const const_space_component&);


    Can anybody throw some light on this error?

    Many thanks,

    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 21, 2009
    #1
    1. Advertising

  2. Helmut Jarausch wrote:
    > I have got the following error message which I don't understand
    >
    > branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool,
    > size_type, const Float&)':
    > branch_E.cc:48882: error: parameter may not have variably modified type
    > 'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) + 1)]'
    >
    >
    > space V = u.get_space();
    > .....
    > // The (preprocessed) failing source line is
    > Form proj (space(V), V_new_i, "mass");
    >


    When you're in the debugger, what's the value of 'V'? You're trying to
    index that pointer, but are you sure it's indexable? Are you sure that
    what you get from 'u.get_space()' is a valid pointer?

    >
    > class Form has the corresponding constructor
    >
    > Form (const space& X, const space& Y, const std::string& op_name,
    > bool locked_boundaries=false);
    >
    > and
    >
    > class space : public smart_pointer<spacerep> {
    > space(const const_space_component&);
    >
    >
    > Can anybody throw some light on this error?


    We can. And to help us help you you should start by reading the FAQ,
    especially the section 5.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 21, 2009
    #2
    1. Advertising

  3. Helmut Jarausch

    James Kanze Guest

    On Oct 21, 2:17 pm, Helmut Jarausch <> wrote:

    > I have got the following error message which I don't understand


    > branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool, size_type, const Float&)':
    > branch_E.cc:48882: error: parameter may not have variably modified type 'space [(((long unsigned int)(((long int)i) +
    > -0x00000000000000001)) + 1)]'


    Are there really more than 48882 lines in your source file?

    > space V = u.get_space();
    > .....
    > // The (preprocessed) failing source line is
    > Form proj (space(V), V_new_i, "mass");


    > class Form has the corresponding constructor


    > Form (const space& X, const space& Y, const std::string& op_name,
    > bool locked_boundaries=false);


    > and


    > class space : public smart_pointer<spacerep> {
    > space(const const_space_component&);


    > Can anybody throw some light on this error?


    Not without more code. What is V, for example, and what is
    the definition of const_space_component? (The error message
    suggests that space(V) is being interpreted as a declaration,
    rather than an expression. I believe some older versions of g++
    had a bug like this; what compiler are you using?)

    --
    James Kanze
     
    James Kanze, Oct 21, 2009
    #3
  4. James Kanze wrote:
    > On Oct 21, 2:17 pm, Helmut Jarausch <> wrote:
    >
    >> I have got the following error message which I don't understand

    >
    >> branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool, size_type, const Float&)':
    >> branch_E.cc:48882: error: parameter may not have variably modified type 'space [(((long unsigned int)(((long int)i) +
    >> -0x00000000000000001)) + 1)]'

    >
    > Are there really more than 48882 lines in your source file?

    Yes, the original file has only 418 lines but I have compiled the output of the preprocessor, i.e. of g++ -E ....


    >
    >> space V = u.get_space();
    >> .....
    >> // The (preprocessed) failing source line is
    >> Form proj (space(V), V_new_i, "mass");

    >
    >> class Form has the corresponding constructor

    >
    >> Form (const space& X, const space& Y, const std::string& op_name,
    >> bool locked_boundaries=false);

    >
    >> and

    >
    >> class space : public smart_pointer<spacerep> {
    >> space(const const_space_component&);

    >
    >> Can anybody throw some light on this error?

    >
    > Not without more code. What is V, for example, and what is
    > the definition of const_space_component? (The error message
    > suggests that space(V) is being interpreted as a declaration,
    > rather than an expression. I believe some older versions of g++
    > had a bug like this; what compiler are you using?)


    First, the code is not by me, but I'd like to just understand
    what the compiler "thinks" is wrong here.
    The compiler is gcc-4.4.2 (the latest release, I think).
    The code base is quite large and meanwhile, the author only told
    me that the code is accepted by gcc-4.3.x .
    So, either gcc-4.4.2 has a bug here or it is stricter than gcc-4.3.x


    How can space(V) be a declaration. It's constructor call
    with the argument V.
    Now, V is of class space which is a specialization of smart_pointer<spacerep>
    and has an operator[] (see below)

    So, V is an object of type space_component (since V is a non-const object).
    But, class space only has a constructor accepting const const_space_component& .
    Fortunately, struct const_space_component has a constructor
    const_space_component(const space_component&);
    such that it should be possible to convert V to an object of
    type const_space_component which itself is accepted by a constructor of
    class space.

    So, why does gcc-4.4.2 reject this? Is it a bug, after all?

    Many thanks for your help,
    Helmut.

    class smart_pointer {
    public:

    // allocators:

    smart_pointer (T* p = 0);
    smart_pointer (const smart_pointer&);
    ~smart_pointer ();
    smart_pointer& operator= (const smart_pointer&);

    // accessors:

    const T* pointer () const;
    const T& data () const;
    const T* operator-> () const;
    const T& operator* () const;

    // modifiers:

    T* pointer ();
    T* operator-> ();
    T& data ();
    T& operator* ();

    };

    and

    class space : public smart_pointer<spacerep> {
    .....
    space_component operator [] (size_type i_comp);
    const_space_component operator [] (size_type i_comp) const;
    ....
    };


    struct const_space_component {
    typedef space::size_type size_type;
    const_space_component();
    const_space_component(const space& V, size_type i);
    const_space_component(const space_component&);
    const space* _pV;
    size_type _i_comp;
    };


    >
    > --
    > James Kanze



    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 21, 2009
    #4
  5. Victor Bazarov wrote:
    .....
    >> Can anybody throw some light on this error?

    >
    > We can. And to help us help you you should start by reading the FAQ,
    > especially the section 5.
    >


    I knew I've delivered too few information to fully understand what's going on.
    But, the code base is quite large and what's even worse, it's not by myself.
    Meanwhile the author (only) told me, the code is accepted by gcc-4.3.x but
    I'm using gcc-4.4.2 .
    So, in a first step, I just wanted to understand the error message (what
    does the compiler "think" is wrong here).

    If you're interested, I've given some more code in a reply to James Kanze's
    answer.

    Helmut.


    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 21, 2009
    #5
  6. Helmut Jarausch wrote:

    > Hi,
    >
    > I have got the following error message which I don't understand
    >
    > branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool,
    > size_type, const Float&)': branch_E.cc:48882: error: parameter may not
    > have variably modified type 'space [(((long unsigned int)(((long int)i) +
    > -0x00000000000000001)) + 1)]'
    >
    >
    > space V = u.get_space();
    > .....
    > // The (preprocessed) failing source line is
    > Form proj (space(V), V_new_i, "mass");
    >
    >
    > class Form has the corresponding constructor
    >
    > Form (const space& X, const space& Y, const std::string& op_name,
    > bool locked_boundaries=false);
    >
    > and
    >
    > class space : public smart_pointer<spacerep> {
    > space(const const_space_component&);
    >
    >
    > Can anybody throw some light on this error?
    >


    The same error is given for the following snippet in 4.4.1

    struct A { A(int, char const*); };
    int main() {
    int i = 0, *b = &i;
    A a(int(b), "hello");
    }

    That's clearly a valid piece of code. GCC fails to check the second
    parameter, which surely cannot ever be a valid declaration. Notice that when
    you miss it, then GCC must interpret the code as a declaration, and reject
    it:

    struct A { A(int, char const*); };
    int main() {
    int i = 0, *b = &i;
    // equivalent: A a(int b);
    A a(int(b)); // error: i is not constant
    }
     
    Johannes Schaub (litb), Oct 21, 2009
    #6
  7. Johannes Schaub (litb) wrote:

    > Helmut Jarausch wrote:
    >
    >> Hi,
    >>
    >> I have got the following error message which I don't understand
    >>
    >> branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool,
    >> size_type, const Float&)': branch_E.cc:48882: error: parameter may not
    >> have variably modified type 'space [(((long unsigned int)(((long int)i) +
    >> -0x00000000000000001)) + 1)]'
    >>
    >> [...snippet...]
    >>

    > The same error is given for the following snippet in 4.4.1
    >
    > struct A { A(int, char const*); };
    > int main() {
    > int i = 0, *b = &i;
    > A a(int(b), "hello");
    > }
    >
    > That's clearly a valid piece of code. GCC fails to check the second
    > parameter, which surely cannot ever be a valid declaration. Notice that
    > when you miss it, then GCC must interpret the code as a declaration, and
    > reject it:
    >
    > struct A { A(int, char const*); };
    > int main() {
    > int i = 0, *b = &i;
    > // equivalent: A a(int b);
    > A a(int(b)); // error: i is not constant
    > }
    >

    There are other ways where GCC's disambiguations go mad. Consider:

    int main() { int const i = 1, p[2] = {}; { int(p), 0; } }

    While you would expect it's a function style cast followed by a zero in a
    comma operator, it is parsed as a declaration, and thus wants to parse "0"
    as a name for a declaration and fails. I don't think GCC is right. It should
    be parsed as an expression.

    This code also fails for GCC 4.1.
     
    Johannes Schaub (litb), Oct 21, 2009
    #7
  8. Johannes Schaub (litb) wrote:
    > Helmut Jarausch wrote:
    >
    >> Hi,
    >>
    >> I have got the following error message which I don't understand
    >>
    >> branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool,
    >> size_type, const Float&)': branch_E.cc:48882: error: parameter may not
    >> have variably modified type 'space [(((long unsigned int)(((long int)i) +
    >> -0x00000000000000001)) + 1)]'
    >>
    >>
    >> space V = u.get_space();
    >> .....
    >> // The (preprocessed) failing source line is
    >> Form proj (space(V), V_new_i, "mass");
    >>
    >>
    >> class Form has the corresponding constructor
    >>
    >> Form (const space& X, const space& Y, const std::string& op_name,
    >> bool locked_boundaries=false);
    >>
    >> and
    >>
    >> class space : public smart_pointer<spacerep> {
    >> space(const const_space_component&);
    >>
    >>
    >> Can anybody throw some light on this error?
    >>

    >
    > The same error is given for the following snippet in 4.4.1
    >
    > struct A { A(int, char const*); };
    > int main() {
    > int i = 0, *b = &i;
    > A a(int(b), "hello");
    > }
    >
    > That's clearly a valid piece of code. GCC fails to check the second
    > parameter, which surely cannot ever be a valid declaration. Notice that when
    > you miss it, then GCC must interpret the code as a declaration, and reject
    > it:
    >
    > struct A { A(int, char const*); };
    > int main() {
    > int i = 0, *b = &i;
    > // equivalent: A a(int b);
    > A a(int(b)); // error: i is not constant
    > }
    >


    Does that mean, it's a bug in gcc-4.4.2 ?


    Many thanks for your comments,
    Helmut.


    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 21, 2009
    #8
  9. Victor Bazarov wrote:
    ....
    >> Can anybody throw some light on this error?

    >
    > We can. And to help us help you you should start by reading the FAQ,
    > especially the section 5.


    Here is a small but complete example to show the problem.
    See the last 4 lines.


    #include <vector>
    using std::vector;
    #include <string>

    struct space_component;
    struct const_space_component;

    template <class T>
    class smart_pointer {
    public:

    // allocators:

    smart_pointer (T* p = 0);
    smart_pointer (const smart_pointer&);
    ~smart_pointer ();
    smart_pointer& operator= (const smart_pointer&);

    // accessors:

    const T* pointer () const;
    const T& data () const;
    const T* operator-> () const;
    const T& operator* () const;

    // modifiers:

    T* pointer ();
    T* operator-> ();
    T& data ();
    T& operator* ();

    // implementation:

    };

    typedef int basis;

    class spacerep {
    public:
    typedef std::vector<basis>::size_type size_type;
    spacerep();
    };


    class space : public smart_pointer<spacerep> {
    public:
    // typdefs:

    typedef spacerep::size_type size_type;

    // allocator/deallocator:

    space ();
    space(const const_space_component&);

    space_component operator [] (size_type i_comp);
    const_space_component operator [] (size_type i_comp) const;
    };

    struct space_component {
    typedef space::size_type size_type;
    space_component();
    space_component(space& V, size_type i);
    };
    struct const_space_component {
    typedef space::size_type size_type;
    const_space_component();
    const_space_component(const space_component&);
    };

    class form {
    public :
    form ();
    form (const space& X, const space& Y, const std::string& op_name,
    bool locked_boundaries=false);

    };

    int main() {
    space V, V_new_i;
    int i=1;
    form proj (space(V), V_new_i, "mass");
    /* error: parameter may not have variably modified type
    'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) + 1)]'
    */

    }

    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 21, 2009
    #9
  10. Helmut Jarausch wrote:
    > Victor Bazarov wrote:
    > ...
    >>> Can anybody throw some light on this error?

    >>
    >> We can. And to help us help you you should start by reading the FAQ,
    >> especially the section 5.

    >
    > Here is a small but complete example to show the problem.
    > See the last 4 lines.
    >
    >
    > [..valid code redacted..]
    >


    Comeau online trial compiles your code without a problem. Obviously
    there is something wrong with the compiler you are using. Try
    contacting the maker of it, upgrade it, downgrade it, or/and even
    post to the newsgroup dedicated to that compiler.

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 22, 2009
    #10
  11. Who is right [was Re: error: parameter may not have variably modifiedtype]

    Victor Bazarov wrote:
    > Helmut Jarausch wrote:
    >> Victor Bazarov wrote:
    >> ...
    >>>> Can anybody throw some light on this error?
    >>>
    >>> We can. And to help us help you you should start by reading the FAQ,
    >>> especially the section 5.

    >>
    >> Here is a small but complete example to show the problem.
    >> See the last 4 lines.
    >>
    >>
    >> [..valid code redacted..]
    >>

    >
    > Comeau online trial compiles your code without a problem. Obviously
    > there is something wrong with the compiler you are using. Try
    > contacting the maker of it, upgrade it, downgrade it, or/and even
    > post to the newsgroup dedicated to that compiler.
    >


    I've created a bug report for gnu.gcc and the answer was

    I don't think this is misparsing this at all. This is one place in the C++
    standard that says it should be parsed as a function declaration rather than a
    variable declaration to resolve an ambiguous between those two.

    So, who is right? Whom to ask next?

    And if it's a function declaration, indeed, how to tell the compiler that I wish
    a variable declaration?

    Many thanks for your help,
    Helmut.

    Here the questionable code again (see the last few lines, first)

    #include <vector>
    using std::vector;
    #include <string>

    struct space_component;
    struct const_space_component;

    template <class T>
    class smart_pointer {
    public:

    // allocators:

    smart_pointer (T* p = 0);
    smart_pointer (const smart_pointer&);
    ~smart_pointer ();
    smart_pointer& operator= (const smart_pointer&);

    // accessors:

    const T* pointer () const;
    const T& data () const;
    const T* operator-> () const;
    const T& operator* () const;

    // modifiers:

    T* pointer ();
    T* operator-> ();
    T& data ();
    T& operator* ();

    // implementation:

    };

    typedef int basis;

    class spacerep {
    public:
    typedef std::vector<basis>::size_type size_type;
    spacerep();
    };


    class space : public smart_pointer<spacerep> {
    public:
    // typdefs:

    typedef spacerep::size_type size_type;

    // allocator/deallocator:

    space ();
    space(const const_space_component&);

    space_component operator [] (size_type i_comp);
    const_space_component operator [] (size_type i_comp) const;
    };

    struct space_component {
    typedef space::size_type size_type;
    space_component();
    space_component(space& V, size_type i);
    };
    struct const_space_component {
    typedef space::size_type size_type;
    const_space_component();
    const_space_component(const space_component&);
    };

    class form {
    public :
    form ();
    form (const space& X, const space& Y, const std::string& op_name,
    bool locked_boundaries=false);

    };

    int main() {
    space V, V_new_i;
    int i=1;
    form proj (space(V), V_new_i, "mass");
    /* error: parameter may not have variably modified type
    'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) + 1)]'
    */

    }


    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 22, 2009
    #11
  12. Re: Who is right [was Re: error: parameter may not have variably modified type]

    Helmut Jarausch wrote:

    > Victor Bazarov wrote:
    >> Helmut Jarausch wrote:
    >>> Victor Bazarov wrote:
    >>> ...
    >>>>> Can anybody throw some light on this error?
    >>>>
    >>>> We can. And to help us help you you should start by reading the FAQ,
    >>>> especially the section 5.
    >>>
    >>> Here is a small but complete example to show the problem.
    >>> See the last 4 lines.
    >>>
    >>>
    >>> [..valid code redacted..]
    >>>

    >>
    >> Comeau online trial compiles your code without a problem. Obviously
    >> there is something wrong with the compiler you are using. Try
    >> contacting the maker of it, upgrade it, downgrade it, or/and even
    >> post to the newsgroup dedicated to that compiler.
    >>

    >
    > I've created a bug report for gnu.gcc and the answer was
    >
    > I don't think this is misparsing this at all. This is one place in the
    > C++ standard that says it should be parsed as a function declaration
    > rather than a variable declaration to resolve an ambiguous between those
    > two.
    >
    > So, who is right? Whom to ask next?
    >
    > And if it's a function declaration, indeed, how to tell the compiler that
    > I wish a variable declaration?
    >
    > Many thanks for your help,
    > Helmut.
    >
    > Here the questionable code again (see the last few lines, first)
    >


    The following is a better testcase for this:

    struct A { A(int, char const*); };
    int main() {
    int i = 0, *b = &i;
    A a(int(b), "hello");
    }

    I might have been too fast yesterday in saying GCC is wrong. Looking again
    today, i'm not sure anymore.

    Any construct that could possibly be a declaration is parsed as a
    declaration. "int(b)" could possibly be a declaration, so GCC parses it
    as a declaration, and will error at "hello".

    There are two interpretations of the ambiguity resolutions. It can be
    considered an ambiguity by noticing it starts out to look like a function
    declaration. The first parameter is looked at, and it is found to be a
    declaration, so the Standard mandates it's taken as a declaration. But if
    that's so, then the whole thing cannot be an object declaration anymore, and
    "hello" is misparsed as a parameter declaration.

    On the other side, if you have "hello" there, there is no ambiguity to begin
    with (i don't think anything requires an implementation to parse stuff from
    left to right???), because the whole thing is unambiguously an object
    declaration. I've thus doubts that 8.2 applies at all. It would thus seem to
    me, using this interpretation, that the Standard still requires the above to
    parse as an object declaration.

    I'm not sure to say anymore whether GCC or comeau is right.
     
    Johannes Schaub (litb), Oct 22, 2009
    #12
  13. Helmut Jarausch

    James Kanze Guest

    Re: Who is right [was Re: error: parameter may not have variablymodified type]

    On Oct 22, 8:31 am, Helmut Jarausch <-aachen.de>
    wrote:
    > Victor Bazarov wrote:
    > > Helmut Jarausch wrote:
    > >> Victor Bazarov wrote:
    > >> ...
    > >>>> Can anybody throw some light on this error?


    > >>> We can. And to help us help you you should start by
    > >>> reading the FAQ, especially the section 5.


    > >> Here is a small but complete example to show the problem.
    > >> See the last 4 lines.


    > >> [..valid code redacted..]


    > > Comeau online trial compiles your code without a problem.
    > > Obviously there is something wrong with the compiler you are
    > > using. Try contacting the maker of it, upgrade it,
    > > downgrade it, or/and even post to the newsgroup dedicated to
    > > that compiler.


    > I've created a bug report for gnu.gcc and the answer was


    > I don't think this is misparsing this at all. This is one
    > place in the C++ standard that says it should be parsed as a
    > function declaration rather than a variable declaration to
    > resolve an ambiguous between those two.


    > So, who is right? Whom to ask next?


    In a certain sense, it doesn't matter. The authors of g++ are
    more or less gods when it comes to their compiler, and if they
    decide on one particular interpretation, and you have to use
    g++, you're stuck with it, even if it doesn't make sense or is
    manifestly wrong.

    > And if it's a function declaration, indeed, how to tell the
    > compiler that I wish a variable declaration?


    > Here the questionable code again (see the last few lines, first)


    [...]
    > form proj (space(V), V_new_i, "mass");
    > /* error: parameter may not have variably modified type
    > 'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) + 1)]'
    > */


    First, there is absolutely no way that proj can be interpreted
    as a function declaration; the string literal prevents that,
    regardless of anything else. Second, if "space" is the
    name of a type (as it is in your code), »space(V)« is a
    function declaration in any context that allows function
    declarations. The only contexts which allow declarations
    other than at the statement level, however, is as part of other
    declarations; the only context in which a function declaration
    can be followed by a comma is as a parameter in another function
    declaration. Since in this case, the string literal means that
    this statement cannot be a function declaration, »space(V
    cannot be a parameter declaration, and thus, cannot be a
    function declaration. There's no ambiguity. (This is a
    difficult parse, however, since the interpretation here depends
    on context. In something like:
    form proj( space(V) );
    »space(V)« is a function declaration, and the entire
    statement is a function declaration, because there is nothing
    which makes it illegal as a function declaration.)

    I do remember earlier versions of g++ (2.95.2?) having problems
    with this; they didn't consider context to the right of the
    expression when making the decision, so something like:
    form proj( space(V), "abc" );
    would fail to compile, treating »space(V)« as a function
    declaration, whereas:
    form proj( "abc", space(V) );
    worked, since the preceding string literal had removed the
    ambiguity of the context. Later versions of g++ fixed this. It
    sounds to me like they've reintroduced the bug, and that someone
    has decided (on what grounds, I don't know), that it's not a
    bug, but a feature.

    At any rate, when in doubt, it never hurts to put an extra set
    of parentheses around the expression, i.e.:
    form proj( (space(V)), V_new_i, "mass" );
    There is no syntax in which a declaration begins with an opening
    parentheses. (Note that you need the extra parentheses; the
    first opening parentheses are part of the outer declaration
    here.)

    --
    James Kanze
     
    James Kanze, Oct 22, 2009
    #13
  14. Helmut Jarausch

    James Kanze Guest

    Re: Who is right [was Re: error: parameter may not have variablymodified type]

    On Oct 22, 10:22 am, "Johannes Schaub (litb)" <>
    wrote:
    > Helmut Jarausch wrote:
    > > Victor Bazarov wrote:
    > >> Helmut Jarausch wrote:
    > >>> Victor Bazarov wrote:
    > >>> ...


    > The following is a better testcase for this:


    > struct A { A(int, char const*); };
    > int main() {
    > int i = 0, *b = &i;
    > A a(int(b), "hello");
    > }


    > I might have been too fast yesterday in saying GCC is wrong.
    > Looking again today, i'm not sure anymore.


    > Any construct that could possibly be a declaration is parsed
    > as a declaration. "int(b)" could possibly be a declaration,
    > so GCC parses it as a declaration, and will error at "hello".


    Context counts. Given something like:
    struct A { A(int); A(); };
    A operator+( A const&, int );
    int main()
    {
    int b;
    {
    A(b) ; // »A(b)« is a declaration
    }
    {
    A(b) + 1; // »A(b)« is an expression (a function
    // style cast)
    }
    }
    In your example, the presence of the string literal means that
    »A a(...)« can't be a function declaration, but must define an
    object, the fact that it defines an object means that the
    contents of the parentheses are arguments (expressions) and not
    parameters (declarations).

    > There are two interpretations of the ambiguity resolutions. It
    > can be considered an ambiguity by noticing it starts out to
    > look like a function declaration. The first parameter is
    > looked at, and it is found to be a declaration, so the
    > Standard mandates it's taken as a declaration. But if that's
    > so, then the whole thing cannot be an object declaration
    > anymore, and "hello" is misparsed as a parameter declaration.


    > On the other side, if you have "hello" there, there is no
    > ambiguity to begin with (i don't think anything requires an
    > implementation to parse stuff from left to right???),


    It's well established that the grammar of C++ is not context
    free.

    > because the whole thing is unambiguously an object
    > declaration. I've thus doubts that 8.2 applies at all. It
    > would thus seem to me, using this interpretation, that the
    > Standard still requires the above to parse as an object
    > declaration.


    8.2 refers to 6.8 to define the ambiguity, and 6.8 does say
    (regretfully in a non-normative note, but this clearly indicates
    the intent) that "the whole statement might have to be examined
    to determine if it is an expression-statement or a declaration."

    > I'm not sure to say anymore whether GCC or comeau is right.


    Given that g++ fixed this once in the past, as a bug, I'd say
    Comeau. (VC++ also accepts your example.)

    --
    James Kanze
     
    James Kanze, Oct 22, 2009
    #14
  15. Re: Who is right [was Re: error: parameter may not have variably modified type]

    James Kanze wrote:

    > On Oct 22, 10:22 am, "Johannes Schaub (litb)" <>
    > wrote:
    >> There are two interpretations of the ambiguity resolutions. It
    >> can be considered an ambiguity by noticing it starts out to
    >> look like a function declaration. The first parameter is
    >> looked at, and it is found to be a declaration, so the
    >> Standard mandates it's taken as a declaration. But if that's
    >> so, then the whole thing cannot be an object declaration
    >> anymore, and "hello" is misparsed as a parameter declaration.

    >
    >> On the other side, if you have "hello" there, there is no
    >> ambiguity to begin with (i don't think anything requires an
    >> implementation to parse stuff from left to right???),

    >
    > It's well established that the grammar of C++ is not context
    > free.
    >

    Dunno yet about all these syntax parsing madness. I've yet to write my own
    compiler by hand :)

    >> because the whole thing is unambiguously an object
    >> declaration. I've thus doubts that 8.2 applies at all. It
    >> would thus seem to me, using this interpretation, that the
    >> Standard still requires the above to parse as an object
    >> declaration.

    >
    > 8.2 refers to 6.8 to define the ambiguity, and 6.8 does say
    > (regretfully in a non-normative note, but this clearly indicates
    > the intent) that "the whole statement might have to be examined
    > to determine if it is an expression-statement or a declaration."
    >

    I've tried to apply that to 8.2 which says "Just as for the ambiguities
    mentioned in 6.8, the resolution is to consider any construct that could
    possibly be a declaration a declaration." But it made no sense to me to
    interpret it that way, since the whole construct is a declaration either
    way, so i came to the conclusion that it's only the sub-
    declarations/expressions that disambiguation depends on in case any
    ambiguity happens at all (in my example there is no ambiguity at all so 8.2
    wouldn't apply, which i'm pretty sure about now too).
     
    Johannes Schaub (litb), Oct 22, 2009
    #15
  16. Helmut Jarausch

    James Kanze Guest

    On Oct 21, 6:53 pm, Helmut Jarausch <> wrote:
    > James Kanze wrote:
    > > On Oct 21, 2:17 pm, Helmut Jarausch <> wrote:


    > >> I have got the following error message which I don't understand


    > >> branch_E.cc: In function 'void put(std::istream&, std::eek:stream&, bool, size_type, const Float&)':
    > >> branch_E.cc:48882: error: parameter may not have variably modified type 'space [(((long unsigned int)(((long int)i) +
    > >> -0x00000000000000001)) + 1)]'


    > >> space V = u.get_space();
    > >> .....
    > >> // The (preprocessed) failing source line is
    > >> Form proj (space(V), V_new_i, "mass");


    > >> class Form has the corresponding constructor


    > >> Form (const space& X, const space& Y, const std::string& op_name,
    > >> bool locked_boundaries=false);


    > >> and

    >
    > >> class space : public smart_pointer<spacerep> {
    > >> space(const const_space_component&);


    > >> Can anybody throw some light on this error?


    > > Not without more code. What is V, for example, and what
    > > is the definition of const_space_component? (The error
    > > message suggests that space(V) is being interpreted as a
    > > declaration, rather than an expression. I believe some
    > > older versions of g++ had a bug like this; what compiler are
    > > you using?)


    > First, the code is not by me, but I'd like to just understand
    > what the compiler "thinks" is wrong here. The compiler is
    > gcc-4.4.2 (the latest release, I think). The code base is
    > quite large and meanwhile, the author only told me that the
    > code is accepted by gcc-4.3.x . So, either gcc-4.4.2 has a
    > bug here or it is stricter than gcc-4.3.x


    > How can space(V) be a declaration. It's constructor call
    > with the argument V.


    It's also a declaration: it defines an array (named V) of i
    instances of space. It contains an extra, unnecessary set of
    parentheses, but they're allowed. Of course, it's only a legal
    declaration if i is an "integral constant expression", i.e. a
    const variable of integral type whose initializer is an integral
    constant expression. Such ambiguities must be resolved by
    context (is a declaration legal here), and if context doesn't
    resolve them, declaration wins over expression, see §6.8 and
    §8.2. The key in your example is in §8.2/2 "[...] The
    resolution is that any construct that could possibly be a
    type-id in its syntactic context shall be considered a type-id."
    In your case, the syntactic context doesn't allow a type-id, so
    the resolution can't choose a type-id. (Note that whether i is
    an integral constant expression doesn't serve to disambiguate,
    since that's not syntactic.)

    [...]
    > So, why does gcc-4.4.2 reject this? Is it a bug, after all?


    IMHO, yes, because of the above quoted paragraph.

    --
    James Kanze
     
    James Kanze, Oct 22, 2009
    #16
  17. Re: Who is right [was Re: error: parameter may not have variably modified type]

    James Kanze wrote:

    > On Oct 22, 8:31 am, Helmut Jarausch <-aachen.de>
    > wrote:
    >> Victor Bazarov wrote:
    >> > Helmut Jarausch wrote:
    >> >> Victor Bazarov wrote:
    >> >> ...
    >> >>>> Can anybody throw some light on this error?

    >
    >> >>> We can. And to help us help you you should start by
    >> >>> reading the FAQ, especially the section 5.

    >
    >> >> Here is a small but complete example to show the problem.
    >> >> See the last 4 lines.

    >
    >> >> [..valid code redacted..]

    >
    >> > Comeau online trial compiles your code without a problem.
    >> > Obviously there is something wrong with the compiler you are
    >> > using. Try contacting the maker of it, upgrade it,
    >> > downgrade it, or/and even post to the newsgroup dedicated to
    >> > that compiler.

    >
    >> I've created a bug report for gnu.gcc and the answer was

    >
    >> I don't think this is misparsing this at all. This is one
    >> place in the C++ standard that says it should be parsed as a
    >> function declaration rather than a variable declaration to
    >> resolve an ambiguous between those two.

    >
    >> So, who is right? Whom to ask next?

    >
    > In a certain sense, it doesn't matter. The authors of g++ are
    > more or less gods when it comes to their compiler, and if they
    > decide on one particular interpretation, and you have to use
    > g++, you're stuck with it, even if it doesn't make sense or is
    > manifestly wrong.
    >
    >> And if it's a function declaration, indeed, how to tell the
    >> compiler that I wish a variable declaration?

    >
    >> Here the questionable code again (see the last few lines, first)

    >
    > [...]
    >> form proj (space(V), V_new_i, "mass");
    >> /* error: parameter may not have variably modified type
    >> 'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) +
    >> 1)]'
    >> */

    >
    > First, there is absolutely no way that proj can be interpreted
    > as a function declaration; the string literal prevents that,
    > regardless of anything else. Second, if "space" is the
    > name of a type (as it is in your code), »space(V)« is a
    > function declaration in any context that allows function
    > declarations.


    This further depends on "V" being a type. If it's a non-type name,
    "space(V)" is an array declaration with redundant parens. If V is a type,
    it's a function declaration.
     
    Johannes Schaub (litb), Oct 22, 2009
    #17
  18. Re: Who is right [was Re: error: parameter may not have variablymodified type]

    Many thanks James and Johannes!

    Helmut.

    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 22, 2009
    #18
  19. Re: Who is right [was Re: error: parameter may not have variablymodified type]

    Johannes Schaub (litb) wrote:
    > James Kanze wrote:
    >
    >> On Oct 22, 8:31 am, Helmut Jarausch <-aachen.de>
    >> wrote:
    >>> Victor Bazarov wrote:
    >>>> Helmut Jarausch wrote:
    >>>>> Victor Bazarov wrote:
    >>>>> ...
    >>>>>>> Can anybody throw some light on this error?
    >>>>>> We can. And to help us help you you should start by
    >>>>>> reading the FAQ, especially the section 5.
    >>>>> Here is a small but complete example to show the problem.
    >>>>> See the last 4 lines.
    >>>>> [..valid code redacted..]
    >>>> Comeau online trial compiles your code without a problem.
    >>>> Obviously there is something wrong with the compiler you are
    >>>> using. Try contacting the maker of it, upgrade it,
    >>>> downgrade it, or/and even post to the newsgroup dedicated to
    >>>> that compiler.
    >>> I've created a bug report for gnu.gcc and the answer was
    >>> I don't think this is misparsing this at all. This is one
    >>> place in the C++ standard that says it should be parsed as a
    >>> function declaration rather than a variable declaration to
    >>> resolve an ambiguous between those two.
    >>> So, who is right? Whom to ask next?

    >> In a certain sense, it doesn't matter. The authors of g++ are
    >> more or less gods when it comes to their compiler, and if they
    >> decide on one particular interpretation, and you have to use
    >> g++, you're stuck with it, even if it doesn't make sense or is
    >> manifestly wrong.
    >>
    >>> And if it's a function declaration, indeed, how to tell the
    >>> compiler that I wish a variable declaration?
    >>> Here the questionable code again (see the last few lines, first)

    >> [...]
    >>> form proj (space(V), V_new_i, "mass");
    >>> /* error: parameter may not have variably modified type
    >>> 'space [(((long unsigned int)(((long int)i) + -0x00000000000000001)) +
    >>> 1)]'
    >>> */

    >> First, there is absolutely no way that proj can be interpreted
    >> as a function declaration; the string literal prevents that,
    >> regardless of anything else. Second, if "space" is the
    >> name of a type (as it is in your code), »space(V)« is a
    >> function declaration in any context that allows function
    >> declarations.

    >
    > This further depends on "V" being a type. If it's a non-type name,
    > "space(V)" is an array declaration with redundant parens. If V is a type,
    > it's a function declaration.


    How can that be? AFAIK, a function declaration has the form

    <Type> <Name>( <Type> <Name>,...)

    Even if 'V' is type name, how are the square brackets interpreted in that case?

    Helmut.



    --
    Helmut Jarausch

    Lehrstuhl fuer Numerische Mathematik
    RWTH - Aachen University
    D 52056 Aachen, Germany
     
    Helmut Jarausch, Oct 22, 2009
    #19
  20. Re: Who is right [was Re: error: parameter may not have variably modified type]

    Helmut Jarausch wrote:

    > Johannes Schaub (litb) wrote:
    >> James Kanze wrote:
    >>
    >>> On Oct 22, 8:31 am, Helmut Jarausch <-aachen.de>
    >>> wrote:
    >>>> Victor Bazarov wrote:
    >>>>> Helmut Jarausch wrote:
    >>>>>> Victor Bazarov wrote:
    >>>>>> ...
    >>>>>>>> Can anybody throw some light on this error?
    >>>>>>> We can. And to help us help you you should start by
    >>>>>>> reading the FAQ, especially the section 5.
    >>>>>> Here is a small but complete example to show the problem.
    >>>>>> See the last 4 lines.
    >>>>>> [..valid code redacted..]
    >>>>> Comeau online trial compiles your code without a problem.
    >>>>> Obviously there is something wrong with the compiler you are
    >>>>> using. Try contacting the maker of it, upgrade it,
    >>>>> downgrade it, or/and even post to the newsgroup dedicated to
    >>>>> that compiler.
    >>>> I've created a bug report for gnu.gcc and the answer was
    >>>> I don't think this is misparsing this at all. This is one
    >>>> place in the C++ standard that says it should be parsed as a
    >>>> function declaration rather than a variable declaration to
    >>>> resolve an ambiguous between those two.
    >>>> So, who is right? Whom to ask next?
    >>> In a certain sense, it doesn't matter. The authors of g++ are
    >>> more or less gods when it comes to their compiler, and if they
    >>> decide on one particular interpretation, and you have to use
    >>> g++, you're stuck with it, even if it doesn't make sense or is
    >>> manifestly wrong.
    >>>
    >>>> And if it's a function declaration, indeed, how to tell the
    >>>> compiler that I wish a variable declaration?
    >>>> Here the questionable code again (see the last few lines, first)
    >>> [...]
    >>>> form proj (space(V), V_new_i, "mass");
    >>>> /* error: parameter may not have variably modified type
    >>>> 'space [(((long unsigned int)(((long int)i) + -0x00000000000000001))
    >>>> + 1)]'
    >>>> */
    >>> First, there is absolutely no way that proj can be interpreted
    >>> as a function declaration; the string literal prevents that,
    >>> regardless of anything else. Second, if "space" is the
    >>> name of a type (as it is in your code), »space(V)« is a
    >>> function declaration in any context that allows function
    >>> declarations.

    >>
    >> This further depends on "V" being a type. If it's a non-type name,
    >> "space(V)" is an array declaration with redundant parens. If V is a
    >> type, it's a function declaration.

    >
    > How can that be? AFAIK, a function declaration has the form
    >
    > <Type> <Name>( <Type> <Name>,...)
    >
    > Even if 'V' is type name, how are the square brackets interpreted in that
    > case?
    >

    It's the declaration of a paramater with "<Name>" omitted:

    <Type> = space, <Name> = epsilon, (,
    <Type> = V, <Name> = epsilon, ..., )

    Notice that the last "<Name>" really ought to be "<declarator>", and then
    it's

    <Type> = V, <declarator> =

    Hope it makes sense.
     
    Johannes Schaub (litb), Oct 22, 2009
    #20
    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. Foo

    Variably modified struct/union and C99

    Foo, Oct 8, 2009, in forum: C Programming
    Replies:
    2
    Views:
    1,188
  2. Poster Matt
    Replies:
    21
    Views:
    1,756
    Poster Matt
    Jun 16, 2010
  3. Shao Miller

    Re: Variably modified arrays

    Shao Miller, Jan 24, 2013, in forum: C Programming
    Replies:
    0
    Views:
    189
    Shao Miller
    Jan 24, 2013
  4. James Kuyper

    Re: Variably modified arrays

    James Kuyper, Jan 24, 2013, in forum: C Programming
    Replies:
    1
    Views:
    197
    Shao Miller
    Jan 24, 2013
  5. Andrey Tarasevich

    Re: Variably modified arrays

    Andrey Tarasevich, Jan 24, 2013, in forum: C Programming
    Replies:
    0
    Views:
    204
    Andrey Tarasevich
    Jan 24, 2013
Loading...

Share This Page