Test for learners

Discussion in 'C++' started by Stefan Ram, Sep 5, 2008.

  1. Stefan Ram

    Stefan Ram Guest

    I have devised two tests for learners of C++:

    1.) When you want to test whether something is an
    expression within a correct program, put a pair of
    parentheses around it. If it is an expression, the
    program will still be correct and the behavior of the
    program will not change.

    2.) When you want to test whether something is a statement
    within a correct program, put a pair of braces around it.
    If it is a statement, the program will still be correct
    and the behavior of the program will not change.

    To make sure that the rules are correct, I would like to know
    whether anyone can find a counterexample. (I am aware of such
    a counterexample in Java, but not in C++.)
     
    Stefan Ram, Sep 5, 2008
    #1
    1. Advertising

  2. Stefan Ram wrote:
    > 2.) When you want to test whether something is a statement
    > within a correct program, put a pair of braces around it.
    > If it is a statement, the program will still be correct
    > and the behavior of the program will not change.


    int i = 5; // Is this a statement?
    std::cout << i << "\n";

    Let's test:

    { int i = 5; }
    std::cout << i << "\n";

    I suppose it isn't. Then what is it?
     
    Juha Nieminen, Sep 5, 2008
    #2
    1. Advertising

  3. Stefan Ram

    Stefan Ram Guest

    Juha Nieminen <> writes:
    >int i = 5; // Is this a statement?


    Yes.

    My rule has failed.

    So, enclosing a statement in braces can change the correctness
    and/or behavior.

    It might still be valid that a program that complies with the
    BNF grammar of C++ will still comply with this grammar when a
    statement is enclosed in an additional pair of braces.
    (But it might be erroneous after the modification for reasons
    of scoping.)

    One also might still ask whether it holds that if enclosing a
    source text in an additional pair of braces does not change
    the behavior, then that source text is a statement.

    But, no, here is a counterexample for this:

    int main(){ int a[ 2 ][ 2 ]={ 0 }; }
    int main(){ int a[ 2 ][ 2 ]={{ 0 }}; }

    So this test only is an indication that something is a
    statement, but not a strict evidence.
     
    Stefan Ram, Sep 5, 2008
    #3
  4. Stefan Ram wrote:
    > I have devised two tests for learners of C++:
    >
    > 1.) When you want to test whether something is an
    > expression within a correct program, put a pair of
    > parentheses around it. If it is an expression, the
    > program will still be correct and the behavior of the
    > program will not change.


    Hm... I'm not sure about the intended scope of this rule. Say in this
    declaration

    int i;

    I can put a pair of parentheses around 'i'

    int (i);

    and get an equivalent program. This still doesn't mean that this
    specific 'i' in this specific context is an expression. It is not. Sure,
    out of context 'i' is a valid expression, but in the above context it is
    a declarator.

    BTW, is your rule supposed to work both ways? I.e. if one can't put the
    braces around it, does that mean it is not an expression? If so, then it
    is not true as well. For example, in this context

    struct A { int i; };

    struct B : A {
    void foo() {
    int A::*p = &A::i; // 'A::i' is an expression in this context
    }
    };

    'A::i' is an expression. However, if I put braces around it as in

    struct B : A {
    void foo() {
    int A::*p = &(A::i); // ERROR
    }
    };

    the program becomes ill-formed.

    > 2.) When you want to test whether something is a statement
    > within a correct program, put a pair of braces around it.
    > If it is a statement, the program will still be correct
    > and the behavior of the program will not change.


    In C++ (as opposed to C, for example) declarations form declaration
    _statements_. Juha already gave you an counterexample where extra braces
    break the code.
     
    Andrey Tarasevich, Sep 5, 2008
    #4
  5. Andrey Tarasevich wrote:
    > ...
    > BTW, is your rule supposed to work both ways? I.e. if one can't put the
    > braces around it, does that mean it is not an expression? If so, then it
    > is not true as well. For example, in this context
    >
    > struct A { int i; };
    >
    > struct B : A {
    > void foo() {
    > int A::*p = &A::i; // 'A::i' is an expression in this context
    > }
    > };
    >
    > 'A::i' is an expression. However, if I put braces around it as in
    >
    > struct B : A {
    > void foo() {
    > int A::*p = &(A::i); // ERROR
    > }
    > };
    >
    > the program becomes ill-formed.
    > ...


    .... although a pedantic person might argue that while 'A::i' is indeed a
    valid expression in 'B::foo', nevertheless 'A::i' in '&A::i' is _not_ a
    sub-expression, but rather a mere 'qualified-id'. There would probably
    be no reason to even consider this pedantic issue, if not for your rule :)
     
    Andrey Tarasevich, Sep 5, 2008
    #5
  6. Stefan Ram

    Stefan Ram Guest

    Andrey Tarasevich <> writes:
    >BTW, is your rule supposed to work both ways? I.e. if one can't
    >put the braces around it, does that mean it is not an expression?


    I was not sure about this, too.

    Now, I see, that these rules are not valid always, so I will
    have to use wording like »often« for these rules.

    BTW: I believe, a qualified-id is an expression, too, because
    it is an id-expression, whis is a primary-expression.
     
    Stefan Ram, Sep 6, 2008
    #6
  7. Stefan Ram

    Default User Guest

    Stefan Ram wrote:

    > Andrey Tarasevich <> writes:
    > > BTW, is your rule supposed to work both ways? I.e. if one can't
    > > put the braces around it, does that mean it is not an expression?

    >
    > I was not sure about this, too.
    >
    > Now, I see, that these rules are not valid always, so I will
    > have to use wording like »often« for these rules.


    Frankly, I'd drop them altogether. Even if they were 100% reliable, I
    don't think they are useful to a student. As they aren't even
    consistently true, their utility is further dimished.



    Brian

    --
    If televison's a babysitter, the Internet is a drunk librarian who
    won't shut up.
    -- Dorothy Gambrell (http://catandgirl.com)
     
    Default User, Sep 6, 2008
    #7
  8. Stefan Ram wrote:

    > 1.) When you want to test whether something is an
    > expression within a correct program, put a pair of
    > parentheses around it. If it is an expression, the
    > program will still be correct and the behavior of the
    > program will not change.


    Putting parentheses around the function name in an unqualified call
    disables ADL; to wit--

    #include <iostream>

    using namespace std;

    namespace N {
    struct S {};
    void f(S) { cout << "N::f()"; };
    }

    int main()
    {
    N::S s;
    f(s); // compiles
    // (f)(s); // doesn't compile
    return 0;
    }


    Martin

    --
    Quidquid latine scriptum est, altum videtur.
     
    Martin Eisenberg, Sep 6, 2008
    #8
  9. Stefan Ram

    James Kanze Guest

    On Sep 6, 1:40 pm, Martin Eisenberg <> wrote:
    > Stefan Ram wrote:
    > > 1.) When you want to test whether something is an
    > > expression within a correct program, put a pair of
    > > parentheses around it. If it is an expression, the
    > > program will still be correct and the behavior of the
    > > program will not change.


    > Putting parentheses around the function name in an unqualified
    > call disables ADL;


    Putting parentheses around the name of a function-style macro
    can unmask a real function which it hid. So without parenthese,
    you get a macro, with them, you don't. And we all know that
    macros can wreck havoc and change the semantics in all sorts of
    ways.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 6, 2008
    #9
  10. Stefan Ram

    Jerry Coffin Guest

    In article <>,
    says...

    [ ... ]

    > I did look up the expression syntax earlier, but now, it's late evening.


    Yes -- one of the possibilities for a primary expression is an id-
    expression, which is either a qualified id or an unqualified id. An
    identifier is an unqualified id (section 5.1).

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 7, 2008
    #10
  11. Stefan Ram

    James Kanze Guest

    On Sep 6, 9:59 pm, "Alf P. Steinbach" <> wrote:
    > * James Kanze:
    > > Putting parentheses around the name of a function-style macro
    > > can unmask a real function which it hid. So without parenthese,
    > > you get a macro, with them, you don't. And we all know that
    > > macros can wreck havoc and change the semantics in all sorts of
    > > ways.


    > I couldn't think of anything when I saw the original article.


    I didn't even try:). But when putting parentheses around a
    function was mentionned, it reminded me of the C days (without
    inline), when the trick was used to allow an implementation to
    make isspace() a macro, but still allow you to take the address
    of the function: isspace is a function style macro, which will
    only be recognized as a macro and expanded as such if it is
    immediately followed by a '(' token: "isspace,", for example,
    doesn't expand the macro, so the code "sees" the external
    function declaration which preceded the macro definition. And
    of course, as soon as "macro" came to mind, I realized that it
    was anythinig goes.

    > And I'm still not sure you guys are right.


    > Is an unparenthesized function name that's part of a function
    > call, really an expression? A function name on its own is an
    > expression, and a complete function call is, but the
    > unparenthesized function name in a call?


    Of course. Otherwise, how could you construct a function call
    expression? (Remember, () is an operator, just like any other
    operator. It can even be overloaded. And if it's not
    overloaded, it's left hand argument can be any expression which
    has function or pointer to function type.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 7, 2008
    #11
  12. Stefan Ram

    Stefan Ram Guest

    James Kanze <> writes:
    >>Is an unparenthesized function name that's part of a function
    >>call, really an expression? A function name on its own is an
    >>xpression, and a complete function call is, but the
    >>unparenthesized function name in a call?

    >Of course. Otherwise, how could you construct a function call
    >expression?


    By a modification of the grammar and the language.
    For example, in Java, the method name is /never/ an
    expression and cannot be written inside of parentheses.
     
    Stefan Ram, Sep 7, 2008
    #12
  13. Stefan Ram

    James Kanze Guest

    On Sep 7, 4:37 pm, -berlin.de (Stefan Ram) wrote:
    > James Kanze <> writes:
    > >>Is an unparenthesized function name that's part of a function
    > >>call, really an expression? A function name on its own is an
    > >>xpression, and a complete function call is, but the
    > >>unparenthesized function name in a call?

    > >Of course. Otherwise, how could you construct a function call
    > >expression?


    > By a modification of the grammar and the language.
    > For example, in Java, the method name is /never/ an
    > expression and cannot be written inside of parentheses.


    And there are no pointers to functions, or even free functions.
    Java's not C++.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 7, 2008
    #13
  14. Alf P. Steinbach wrote:
    >
    > And I'm still not sure you guys are right.
    >
    > Is an unparenthesized function name that's part of a function call,
    > really an expression?


    Yes.

    > A function name on its own is an expression, and a
    > complete function call is, but the unparenthesized function name in a call?


    Yes, it is an expression. With an ordinary function it is pretty
    obvious, since you can always use the function name alone as a valid
    (albeit useless) expression

    void foo();

    foo; // <- a valid expression

    With member functions things are a bit more complicated. One can't use a
    qualified name of a member function as a standalone expression

    struct S { void foo(); };

    S::foo; // <- ill-formed

    which often leads people to conclude that a member function name alone
    is not an expression. In reality, from the language point of view, it is
    an expression, but it is only allowed to be used in a restricted set of
    contexts, as described in 5/10.
     
    Andrey Tarasevich, Sep 8, 2008
    #14
    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. Sting
    Replies:
    5
    Views:
    1,639
    Natty Gur
    Jun 8, 2004
  2. Robert Allan Schwartz
    Replies:
    7
    Views:
    384
    Marco Manfredini
    Aug 13, 2004
  3. Chris
    Replies:
    1
    Views:
    673
    Chris
    May 11, 2006
  4. Edvard Majakari
    Replies:
    4
    Views:
    695
    Edvard Majakari
    Feb 25, 2005
  5. Skybuck Flying

    Call oddities: &Test() vs &Test vs Test

    Skybuck Flying, Oct 4, 2009, in forum: C Programming
    Replies:
    1
    Views:
    726
    Skybuck Flying
    Oct 4, 2009
Loading...

Share This Page