Assert command

This is a discussion on Assert command within the C Programming forums, part of the General Programming Boards category; I had an interview a while ago, one of the questions had to do with the assert command. Lets say ...

  1. #1
    Registered User
    Join Date
    Sep 2008
    Posts
    27

    Assert command

    I had an interview a while ago, one of the questions had to do with the assert command.

    Lets say I had the below statement:
    Code:
    //main
    assert(foo(MAXINT)) //is this the correct usage of assert?
    
    //foo function
    int foo(int i)
    {
       return i+1;
    }
    now obviously the function foo will return a garbage value since it will overflow, will assert be able to catch this, if not what do I need to prevent the program compiling?

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Assert will blow the whistle if the thing you give it is false. foo(MAXINT) is going to be ... something, most likely a large negative number; but large negative values are true, so that won't help.

    And there's nothing you can do to prevent the program compiling, because there is no error. assert is runtime only.

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> now obviously the function foo will return a garbage value since it will overflow, will assert be able to catch this, if not what do I need to prevent the program compiling?

    First of all, 'assert' is just a macro. Something along the lines of:

    Code:
    #define assert( condition ) do{ if( !( condition ) ) exit( 1 ); } while( 0 );
    There is, of course, more to it than that, but that's the general idea. Second, it isn't really feasible to do a compile-time check - you'll have to do that at runtime (probably somewhere inside 'foo').
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  4. #4
    Registered User
    Join Date
    Sep 2008
    Posts
    27
    lets say instead of MAXINT I put in a negative number, however I want my program to not compile if this is the case how would I go about doing that?

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    It is not physically possible to do what you want. Often times your function and your main function won't even be compiled at the same time! There's no way to share information about what should be valid input and what not. And for that matter, what about this?
    Code:
    printf("Enter a number: ");
    scanf("%d", &bob);
    foo(bob); //compiles?  yes?  no?  who knows?
    Edit: Of course, if you turn foo into
    Code:
    unsigned int foo(unsigned int)
    well foo(-1) will still compile but you'll get a warning out of it.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,794
    If we look in terms of pre-conditions, a pre-condition of foo() is that its argument must be less than the largest int value. This could be expressed in an assertion:
    Code:
    int foo(int i)
    {
        assert(i < INT_MAX);
        return i+1;
    }
    But if foo() is called with user input, then when the program is compiled in some release configuration where assertions are turned off, the pre-condition could still fail if the caller does not perform such a check before calling foo(). Depending on circumstances one might throw an exception instead of using an assertion.

    Nonetheless, as tabstop noted this problem (whether the int argument is the largest integer or a negative number) cannot be be generally detected at compile time since the value of i is only known at runtime.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,668
    C does not have any facilities for a compile-time assert anyway (unlike C++).
    Also, when using assert, form a boolean condition. Say, you do not want the number to be negative? Then you do:
    Code:
    //main
    assert(foo(MAXINT) >= 0) // Number must be greater or equal or 0, or it will fal
    
    //foo function
    int foo(int i)
    {
       return i+1;
    }
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Apr 2006
    Posts
    137
    I think asserts should only be used for dangerous inputs that cannot be foreseen but is created by the program rather than directly by the user.

    And of course, during debug testing.

    You should try and modify your own assert really.

    About this tho, I have a question:
    Code:
    #define assert( condition ) do{ if( !( condition ) ) exit( 1 ); } while( 0 );
    I seen this a lot, but I never quite get why they need the do while loop. There must be a reason...

    Actually, the best idea is to use assert with file logging.
    ★ Inferno provides Programming Tutorials in a variety of languages. Join our Programming Forums. ★

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,794
    Quote Originally Posted by execute
    I think asserts should only be used for dangerous inputs that cannot be foreseen but is created by the program rather than directly by the user.
    Agreed on the part that it should not be relied on to check for user input, though I regard it as useful to check pre-conditions rather than just "dangerous inputs". Incidentally, this is C so my suggestion of exceptions does not apply.

    Quote Originally Posted by execute
    I seen this a lot, but I never quite get why they need the do while loop. There must be a reason...
    It is a trick to avoid problems with scope in macros (though I believe that the terminating semi-colon is usually excluded), e.g., so that an else clause that follows will not be matched with the if in the assertion.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,307
    Quote Originally Posted by execute View Post
    II seen this a lot, but I never quite get why they need the do while loop. There must be a reason...
    Preprocess and compile this and see the reason why:
    Code:
    #define DO_WHILE_EXPLANATION(x) x *= 2; x+=3;
    #define DO_WHILE_EXPLANATION_FIXED(x) do { x *= 2; x+=3; } while(0)
    
    int main ()
    {
        int x = 0;
        while (x < 100) {
            if (x & 1)
                DO_WHILE_EXPLANATION(x);
            else
                ++x;
        }
        return x;
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  11. #11
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,307
    Quote Originally Posted by Albinoswordfish View Post
    what do I need to prevent the program compiling?
    You need a compile-time assert (and a compile-time-constant expression). This is sometimes defined as C_ASSERT as in MSVC. Boost also has one, which generates nicer error messages.
    Usage:
    Code:
    C_ASSERT(MAXINT + 1 >= 0);
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,794
    Quote Originally Posted by iMalc
    You need a compile-time assert (and a compile-time-constant expression).
    Yes, but how does that apply to the actual question? I am not very familiar with static assertions, so would the compiler allow this?
    Code:
    C_ASSERT(foo(MAXINT) > MAXINT);
    Of course, we are assuming that MAXINT is a macro constant, but there is nothing that says that it is not a variable besides the hint provided by the fully capitalised name.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    Code:
    //main
    assert(foo(MAXINT)) //is this the correct usage of assert?
    
    //foo function
    int foo(int i)
    {
       return i+1;
    }
    It won't work if int is signed, because it will wrap around to the most negative value (assuming MAXINT is the same as INT_MAX in limits.h).

    This will work, however (the assert will be triggered) -
    Code:
    //main
    assert(foo(UINT_MAX)) //is this the correct usage of assert?
    
    //foo function
    unsigned int foo(unsigned int i)
    {
       return i+1;
    }
    since it will wrap around to 0, which evaluates to false.

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,794
    To answer my own question about compile time assertions: BOOST_STATIC_ASSERT does not like the function call in foo(INT_MAX) even though the return value is guaranteed to be constant in this special case. It seems like even if MAXINT really is a macro constant rather than a variable that could depend on user input at runtime, trying to detect the given error at compile time is impossible even with a static assertion.

    cyberfish: note the point about detecting the error at compile time.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,183
    cyberfish: note the point about detecting the error at compile time.
    Ah sorry. Missed that point. Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 26
    Last Post: 07-05-2010, 10:43 AM
  2. problem with "touch" command in c program
    By Moony in forum C Programming
    Replies: 10
    Last Post: 08-01-2006, 09:56 AM
  3. Batch file programming
    By year2038bug in forum Tech Board
    Replies: 10
    Last Post: 09-05-2005, 03:30 PM
  4. Ping problem
    By bladerunner627 in forum C++ Programming
    Replies: 12
    Last Post: 02-02-2005, 11:54 AM
  5. exe files in -c- language
    By enjoy in forum C Programming
    Replies: 6
    Last Post: 05-18-2004, 04:36 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21