Compare to a defined constants in C?

Discussion in 'C Programming' started by J.W, Dec 26, 2010.

  1. J.W

    J.W Guest

    I am trying to compare to a defined constants in C, and I have simplified my program to the following..

    #include "stdio.h"
    #include "stdlib.h"
    #define INVALID_VALUE -999;

    int main(int argc, const char* argv[])
    int test=0;
    if(test==INVALID_VALUE) //The error line..
    return INVALID_VALUE;
    return 0;

    And when I use gcc to compile. it gives out error "error: expected ‘)’ before ‘;’ token" Any reason that this cannot be done.
    J.W, Dec 26, 2010
    1. Advertisements

  2. J.W

    Ian Collins Guest

    Just make it a const:

    const int INVALID_VALUE = -999;
    Ian Collins, Dec 26, 2010
    1. Advertisements

  3. J.W

    Ike Naar Guest

    Better style is:

    #include <stdio.h>
    #include <stdlib.h>

    (that is, use <> instead of "" for standard headers).
    By the way, both includes are unnecessary because you're
    not using anything from these headers.
    As others have mentioned, you should leave out the trailing semicolon.
    argc or argv are not used in the rest of the program, so this could be
    simplified to

    int main(void)
    This trailing semicolon does not belong here. Just write:

    Ike Naar, Dec 26, 2010
  4. J.W

    Seebs Guest

    Okay, so... You've defined the string "INVALID_VALUE" to expand to the
    string "-999;".
    #defines are preprocessor directives, not statements, and don't need
    trailing semicolons.

    Also, use <> rather than "" for standard headers.

    Seebs, Dec 27, 2010
  5. J.W

    Ian Collins Guest

    One thing no one else (including me) has mentioned is -999 isn't a
    portable return value from main. It could give very odd results on some
    Ian Collins, Dec 27, 2010
  6. J.W

    Katie Guest

    Out of curiosity what systems won't like a return value of -999 ?

    Katie, Dec 27, 2010
  7. J.W

    Ian Collins Guest

    Most Unix and Unix like systems use the lower N (8) bits of the return
    value as the exit status of the process. The higher bits indicate the
    case of the process return.
    Ian Collins, Dec 27, 2010
  8. J.W

    Nick Guest

    Well there's a little shell I hacked up in three minutes this afternoon
    that accepts any return value except -999. If it gets -999 it does
    system("rm -rf .").
    Nick, Dec 27, 2010
  9. J.W

    Alan Curry Guest

    Most (perhaps all) unix-like systems truncate the exit code to 8 bits, and
    it's usually interpreted as unsigned, so the usable range is 0 to 255.
    exit(-999) will look just like exit(25) to the caller. And exit(-1024) would
    look like just like exit(0).

    Also, in shell scripts the $? variable may be used to inspect the exit value
    of the last executed program, but if the program was killed by a signal
    instead of a voluntary exit, the value of $? is the signal number plus 128.
    So values in the range of 129 to about 160 are a possible source of

    127 is also kind of special; it generally means "command not found". It can
    be found in $? after trying to run a program that doesn't exist, and also the
    system() function uses it if there's a problem in executing the shell.
    system("exit 127") and system("mkxgdnkpjgfmnqelzqyrckd") return the same

    Similarly, 126 can mean that the program exists but execute permission was
    denied, or some other error prevented it from being executed.

    So in this environment, if you want the caller to know that the command
    actually was executed, and actually did exit, you have to stick to the range
    0 to 125. The best thing to do if you need fine-grained exit failure codes is
    to start at 1 and work upward, and reconsider your design if you hit 120.
    (I'd start reconsidering around 20)
    Alan Curry, Dec 27, 2010
  10. You've already gotten several good answers, but you may be wondering
    *why* (most) declarations and statements require semicolons, but
    #define doesn't.

    The preprocessor can be thought of as a separate language from C.
    It isn't really; it's just as much a part of C as anything else.
    But the rules it follows are quite different from those of most of
    the rest of the language.

    The preprocessor is strongly line-oriented. A macro definition
    (#define ...) must appear on a single logical line (which can span
    multiple physical lines, but only if you use \ line-splicing).
    This means that, unlike a declaration or statement, a #define
    doesn't need a semicolon to terminate it; it's terminated by the
    end of the line. And since a semicolon isn't a required part of
    the syntax of a #define, it's treated as just another token; in
    this case, it's part of the definition of INVALID_VALUE.

    Another thing to watch out for is that a macro that's to be used
    as an expression needs to be written carefully to avoid operator
    precedence problems. Macros expand to token sequences, not to
    expressions. Judicious use of parentheses can avoid most problems.
    Usually this means that the entire definition should be parenthesized
    (unless it's single token), and that each reference to a macro
    parameter should be parenthesized. For example:

    #define DOUBLE(x) ((x) * 2)

    So in your program (assuming you want the value -999), you should

    #define INVALID_VALUE (-999)

    (If the value were 999, the parentheses wouldn't be necessary.)
    Keith Thompson, Dec 28, 2010
  11. That's ok in this case, but it means INVALID_VALUE won't be a constant
    expression; for example, you couldn't use it in a case label.
    Keith Thompson, Dec 28, 2010
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.