Syntax error?

Discussion in 'C Programming' started by Jeremy Yallop, Oct 20, 2003.

  1. Looking over some code I came across a line like this

    if isalnum((unsigned char)c) {

    which was accepted by the compiler without complaint. Should the
    compiler have issued a diagnostic in this case? (I think it's not
    required to, but I'd like confirmation).

    Jeremy.
     
    Jeremy Yallop, Oct 20, 2003
    #1
    1. Advertising

  2. In article <bn1l1u$s5l1v$-berlin.de>,
    Jeremy Yallop <> wrote:
    >Looking over some code I came across a line like this
    >
    > if isalnum((unsigned char)c) {
    >
    >which was accepted by the compiler without complaint. Should the
    >compiler have issued a diagnostic in this case? (I think it's not
    >required to, but I'd like confirmation).


    isalnum probably expands to something that's wrapped with parens.
    F'rexample, on a random system readily accessible to me:
    --------
    dave@hct-cvs:~/clc (0) $ cat jy-for-syntax-expand-isalnum.c
    #include <ctype.h>
    #include <stdio.h>

    #define STR(x) STR_(x)
    #define STR_(x) #x

    int main(void)
    {
    printf("isalnum(x) expands to %s\n",STR(isalnum(x)));

    return 0;
    }
    dave@hct-cvs:~/clc (0) $ gcc -W -Wall -ansi -pedantic -O -c jy-for-syntax-expand-isalnum.c
    dave@hct-cvs:~/clc (0) $ ./a.out
    isalnum(x) expands to (__ctype_b[(int) ((x))] & (unsigned short int) _ISalnum)
    dave@hct-cvs:~/clc (0) $
    --------
    so "if isalnum(foo)" would be expanded to
    "if (expansion_of_isalnum_with_parens)", which is valid.

    If this weren't the case it would be, if I'm not mistaken, a syntax
    error that requires a diagnostic. GCC appears to agree with me:
    --------
    dave@hct-cvs:~/clc (0) $ cat jy-for-syntax-broken-if.c
    int bogus_function(int);

    #include <stdio.h>

    int main(void)
    {
    if bogus_function(42)
    {
    puts("bogus_function() returned nonzero");
    }

    return 0;
    }
    dave@hct-cvs:~/clc (0) $ gcc -W -Wall -ansi -pedantic -O -c jy-for-syntax-broken-if.c
    jy-for-syntax-broken-if.c: In function `main':
    jy-for-syntax-broken-if.c:7: parse error before `bogus_function'
    jy-for-syntax-broken-if.c:10: warning: control reaches end of non-void function
    dave@hct-cvs:~/clc (1) $
    --------


    dave

    --
    Dave Vandervies
    Have some pride, you're a physics major! You know deep in your heart
    you're better than the rest of the slobs there, you should be able to
    knock this course off easily. --Brian B. Rodenborn in comp.lang.c
     
    Dave Vandervies, Oct 20, 2003
    #2
    1. Advertising

  3. Jeremy Yallop wrote:
    > Looking over some code I came across a line like this
    >
    > if isalnum((unsigned char)c) {
    >
    > which was accepted by the compiler without complaint. Should the
    > compiler have issued a diagnostic in this case? (I think it's not
    > required to, but I'd like confirmation).


    Presumably this is accepted because 'isalnum' is a macro that happens to
    have a form that makes the syntax valid. You probably knew that already,
    but some people reading might not.

    I don't know for sure, but I don't think the standard mandates anything
    particular about the form of the 'is*' and 'to*' macros (if they even
    exist), other than the requirement that they evaluate their argument
    exactly once.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Oct 20, 2003
    #3
  4. Jeremy Yallop

    Eric Sosman Guest

    Jeremy Yallop wrote:
    >
    > Looking over some code I came across a line like this
    >
    > if isalnum((unsigned char)c) {
    >
    > which was accepted by the compiler without complaint. Should the
    > compiler have issued a diagnostic in this case? (I think it's not
    > required to, but I'd like confirmation).


    It's bad code, but not necessarily incorrect code.
    For example, here's one of the several definitions of
    isalnum() on the system I happen to be using at the
    moment (exactly which definition you get depends on a
    lot of environmental things):

    #define isalnum(c) (__ctype_mask[c] & _ISALNUM)

    Note the parentheses surrounding the replacement. Once
    the macro is expanded in the context you've shown, you'll
    have

    if (__ctype_mask((unsigned char)c) & _ISALNUM) {

    .... which is syntactically correct (as far as it goes).

    Of course, relying on this would be a mistake.

    --
     
    Eric Sosman, Oct 20, 2003
    #4
  5. Jeremy Yallop

    CBFalconer Guest

    Jeremy Yallop wrote:
    >
    > Looking over some code I came across a line like this
    >
    > if isalnum((unsigned char)c) {
    >
    > which was accepted by the compiler without complaint. Should the
    > compiler have issued a diagnostic in this case? (I think it's not
    > required to, but I'd like confirmation).


    It is necessary and absolutely correct, apart from the missing set
    of parenthesis. isalnum() is a standard function, prototyped in
    ctype.h. The standard (N869) says:

    7.4 Character handling <ctype.h>

    [#1] The header <ctype.h> declares several functions useful
    for testing and mapping characters.155) In all cases the
    argument is an int, the value of which shall be
    representable as an unsigned char or shall equal the value
    of the macro EOF. If the argument has any other value, the
    behavior is undefined.

    Without the cast the result would be undefined on any system where
    char is signed.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Oct 21, 2003
    #5
  6. Jeremy Yallop <> wrote in message news:<bn1l1u$s5l1v$-berlin.de>...
    > Looking over some code I came across a line like this
    >
    > if isalnum((unsigned char)c) {
    >
    > which was accepted by the compiler without complaint. Should the
    > compiler have issued a diagnostic in this case? (I think it's not
    > required to, but I'd like confirmation).
    >
    > Jeremy.


    The macro issue aside...

    5.1.1.3 Diagnostics

    1 A conforming implementation shall produce at least one diagnostic message
    (identified in an implementation-defined manner) if a preprocessing
    translation unit or translation unit contains a violation of any syntax
    rule or constraint,...

    --
    Peter
     
    Peter Nilsson, Oct 21, 2003
    #6
  7. Eric Sosman wrote:
    > Jeremy Yallop wrote:
    >>
    >> Looking over some code I came across a line like this
    >>
    >> if isalnum((unsigned char)c) {
    >>
    >> which was accepted by the compiler without complaint. Should the
    >> compiler have issued a diagnostic in this case? (I think it's not
    >> required to, but I'd like confirmation).

    >
    > It's bad code, but not necessarily incorrect code.


    Thanks for the responses, everyone. They answered the question I
    /meant/ to ask, although my post was a bit elliptic. For the record,
    what I wanted to ask regarding the line of code above was something
    like:

    "I know that a syntax error requires a diagnostic. Clearly the
    code above contains a syntax error if "isalnum" is a normal
    function. Ony my system, isalnum is (also) defined as a macro
    which expands to an expression enclosed in parentheses. As this
    makes the above syntactically valid, no warning is issued. Is
    this allowed? i.e. can the macro alternative to a standard
    function expand into code that stops the issuance of a diagnostic
    that would otherwise be required?"

    > Of course, relying on this would be a mistake.


    Understood :).

    Jeremy.
     
    Jeremy Yallop, Oct 21, 2003
    #7
  8. Jeremy Yallop

    Dan Pop Guest

    In <bn1l1u$s5l1v$-berlin.de> Jeremy Yallop <> writes:

    >Looking over some code I came across a line like this
    >
    > if isalnum((unsigned char)c) {
    >
    >which was accepted by the compiler without complaint. Should the
    >compiler have issued a diagnostic in this case? (I think it's not
    >required to, but I'd like confirmation).


    It entirely depends on what the compiler is seeing in translation phase 7,
    when the syntactical analysis of this statement takes place. If there is
    an "#undef isalnum" in effect anywhere between the inclusion of <ctype.h>
    and this statement, the diagnostic is required, of course.

    Your example is no different from

    if FOO {

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Oct 21, 2003
    #8
    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. Balaji
    Replies:
    3
    Views:
    10,194
  2. gabriele renzi
    Replies:
    2
    Views:
    238
    gabriele renzi
    Dec 31, 2005
  3. Ken Bloom
    Replies:
    3
    Views:
    242
  4. Good Night Moon
    Replies:
    9
    Views:
    315
    Rick DeNatale
    Jul 25, 2007
  5. Mark Richards
    Replies:
    3
    Views:
    346
    Tad McClellan
    Nov 18, 2007
Loading...

Share This Page