Problem creating own assert()

Started by
20 comments, last by kordova 21 years ago
I've copied this code line by line from Practical C++ by Rob McGregor: BAssert.h
    
/*********************************************************
*   Module : BAssert.h
*
*   Purpose: Custom assert() and ASSERT() macros
*********************************************************/

#ifndef __BASSERT_H__
#define __BASSERT_H__

// Replace any existing assert and ASSERT with the

// macros in this file


#ifdef assert
    #undef assert
#endif

#ifdef ASSERT
    #undef ASSERT
#endif

// Define assert and ASSERT for debug and

// release builds


#if defined(_DEBUG)

    // Define the debug macros


    #define assert                              \

        if(!)                                  
        {                                      
            cerr << "\nAssertion Failed: " << #a   
                << "\nFailure occured on line "    
                << _LINE_ << " of source file:"    
                << "\n  \"" << _FILE_ << "\"\n";   
        }


    #define  ASSERT(a,str)                      \

        if(!)                                 
        {                                       \                                 
            cerr << "\nAssertion Failed: " << #a  
                << " " << #str                    
                << "\nFailure occured on line "   
                << _LINE_ << " of source file:"   
                << "\n  \"" << _FILE_ << "\"\n";  
        }
#else

    // Define the release macros as nothing

    //

    #define assert
    #define ASSERT(a,str)

#endif  // #if defined(_DEBUG)


#endif // __BASSERT_H__

   
the driver program...main.cpp
  
/*********************************************************
*   Module : main.cpp
*
*   Purpose : A driver program to demonstrate the
*             assert() and ASSERT() macros defined in
*             BAssert.h
*********************************************************/

#include <iostream.h>
#include "BAssert.h"

// Constant definitions
//
const int hearts    = 0;
const int diamonds  = 1;
const int clubs     = 2;
const int spades    = 3;

// Function prototypes
//
void Print(char *str);
void PrintSuit(int suit);
int NotYetImplemented();

/*******************************************************/
//  main()

void main() {
    assert(false);  // Always fails

    int x = 5;
    assert(x==5);   // this on''s okay
    assert(x==10);  //this on''s an error

    ASSERT(x==10,"x should be 5!");
    assert("This will fail" == 0); // Always fails

    char *str1 = 0;
    char *str2 = "\nA test string\n\n";

    Print(str1);
    Printf(str2);

    PrintSuit(hearts);
    PrintSuit(spades);
    PrintSuit(10);

    int y = NotYetImplemented();
}

/*******************************************************/
//  Print()

void Print(char *str) {
    ASSERT(str==0, "String should not be null");
    if(str!=0)
        cout<<str;
}

/*******************************************************/
//  PrintSuit()

void PrintSuit(int suit) {
    switch (suit)
        case hearts:
            cout<<"Hearts\n";
            break;
        case diamonds:
            cout<<"Diamonds\n";
            break;
        case clubs:
            cout<<"Clubs\n";
            break;
        case spades:
            cout<<"Spades\n";
            break;
        default:
            // Invalid suit detected
            assert"Invalid suit detected"==0);
    }
}

/*******************************************************/
//  NotYetImplemented


int NotYetImplemented() {
    assert("Function not yet implemented" == 0);
    return 0;
}
  
And I get the following errors:
        
c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\useoldio.h(29): warning C4995:''_OLD_IOSTREAMS_ARE_DEPRECATE'': name was marked as #pragma deprecated
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\BAssert.h(41): error C2143: syntax error : missing'''' before''<<''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\BAssert.h(41): error C2501:''cer'' : missing storage-class or type specifiers
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\BAssert.h(41): error C2371:''cer'' : redefinition; different basic types
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\BAssert.h(41): error C2014: preprocessor command must start as first nonwhite space
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2059: syntax error :''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2143: syntax error : missing'''' before''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2121:'''' : invalid character : possibly the result of a macro expansion
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2065:'''' : undeclared identifier
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2593:''operator <<'' is ambiguous
        c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\ostream.h(87): could be''ostream &ostream::operator <<(streambuf *''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2065:''_LINE'' : undeclared identifier
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(29): error C2065:''_FILE'' : undeclared identifier
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(32): error C2059: syntax error :''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(32): error C2143: syntax error : missing'''' before''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(32): error C2121:'''' : invalid character : possibly the result of a macro expansion
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(32): error C2593:''operator <<'' is ambiguous
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(33): error C2059: syntax error :''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(33): error C2143: syntax error : missing'''' before''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(33): error C2121:'''' : invalid character : possibly the result of a macro expansion
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(33): error C2593:''operator <<'' is ambiguous
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(35): error C2059: syntax error :''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(35): error C2143: syntax error : missing'''' before''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(35): error C2017: illegal escape sequence
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(36): error C2059: syntax error :''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(36): error C2143: syntax error : missing'''' before''''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(36): error C2121:'''' : invalid character : possibly the result of a macro expansion
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(36): error C2593:''operator <<'' is ambiguous
        c:\Program Files\Microsoft Visual Studio .NET\Vc7\include\ostream.h(87): could be''ostream &ostream::operator <<(streambuf *''
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(42): error C2065:''Print'' : undeclared identifier
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(44): error C2065:''heart'' : undeclared identifier
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(54): error C2601:''Prin'' : local function definitions are illegal
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(55): error C2017: illegal escape sequence
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(79): error C2121:'''' : invalid character : possibly the result of a macro expansion
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(86): error C2601:''NotYetImplemente'' : local function definitions are illegal
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(87): error C2121:'''' : invalid character : possibly the result of a macro expansion
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(90): fatal error C1075: end of file found before the left brace'''' at''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(28'' was matched
    
Does it have to do with the use of cerr? Aside from that ''m not really sure where to begin...Thanks in advance. [edited by - kordova on March 6, 2003 4:35:44 PM]
Advertisement
Looks like there is a problem with the lower case assert. The macro utilizes an argument that isn''t there, ie #a . The hash before the parameter ( #a ) indicates that the macro parameter should be interpretted as a string literal.

Try changing the start of the macro to something like this

#define assert(a) \
if (!a ) \
...

Also note that there can be no whitespace following the backslash \ at the end of each line
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
also do this instead of including iostream.h

#include <iosstream>
using namespace std;

thatl get rid of the warnings of depreciation.
<=- Talon -=>
And the _LINE and _FILE macros are usually called __LINE__ and __FILE__.
In addition you might want to play with __FUNC__ if you''re defining your own asserts.

-Neophyte

I changed the __FILE__ and __LINE__ in the header and the and namespace in the .cpp...

heres the changed .h:


  /**********************************************************   Module : BAssert.h**   Purpose: Custom assert() and ASSERT() macros*********************************************************/#ifndef __BASSERT_H__#define __BASSERT_H__// Replace any existing assert and ASSERT with the// macros in this file#ifdef assert    #undef assert#endif#ifdef ASSERT    #undef ASSERT#endif// Define assert and ASSERT for debug and// release builds#if defined(_DEBUG)    // Define the debug macros    #define assert(a)                            \        if (!a)                                 \        {                                       \            cerr << "\nAssertion Failed: " << #a    \                << "\nFailure occured on line "     \                << __LINE__ << " of source file:"     \                << "\n  \"" << __FILE__ << "\"\n";    \        }    #define  ASSERT(a,str)                      \        if(!)                                   \        {                                       \            cerr << "\nAssertion Failed: " << #a    \                << " " << #str                      \                << "\nFailure occured on line "     \                << __LINE__ << " of source file:"     \                << "\n  \"" << __FILE__ << "\"\n";    \        }#else    // Define the release macros as nothing    //    #define assert(a)    #define ASSERT(a,str)#endif  // #if defined(_DEBUG)#endif // __BASSERT_H__  


I tried adding (a) and (!a) but it gave me a ton of errors:

  c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(34): warning C4806: ''=='' : unsafe operation: no value of type ''bool'' promoted to type ''int'' can equal the given constantc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(35): warning C4806: ''=='' : unsafe operation: no value of type ''bool'' promoted to type ''int'' can equal the given constantc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(37): error C2059: syntax error : '')''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(37): error C2143: syntax error : missing '';'' before ''{''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(44): error C2065: ''Printf'' : undeclared identifierc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(57): error C2059: syntax error : '')''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(57): error C2143: syntax error : missing '';'' before ''{''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(69): error C2043: illegal breakc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(70): error C2046: illegal casec:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(72): error C2043: illegal breakc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(73): error C2046: illegal casec:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(75): error C2043: illegal breakc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(76): error C2046: illegal casec:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(78): error C2043: illegal breakc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(79): error C2047: illegal defaultc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(81): error C2065: ''assert'' : undeclared identifierc:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(81): error C2143: syntax error : missing '';'' before ''string''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(81): error C2059: syntax error : '')''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(81): warning C4553: ''=='' : operator has no effect; did you intend ''=''?c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(83): error C2059: syntax error : ''}''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(83): error C2143: syntax error : missing '';'' before ''}''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(83): error C2059: syntax error : ''}''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(88): error C2143: syntax error : missing '';'' before ''{''c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(88): error C2447: ''{'' : missing function header (old-style formal list?)  


hmmm...thanks again.
Just something fun to be aware of with macro''s if your using .net .

There is a bug in Visual Studio .net (which applies to C++ .net as well) which doesn''t read white space correctly. So if after one of your line continuing \''s you have any spaces or tabs the compiler will blow chunks & never compile the code.
Ah, sweet .net...

I removed all spaces and \''s (put it all on one line basically) and I''ve gotten the same errors... :-\
Perhaps it's the source tags, but this time the capitalized assert fails to adequately check the parameter condition - ie. if (!)

When developing macros it usually helps to isolate them completely from your project and run them through the compiler using the -E switch to examine the exact code that they produce.

For example, at the bottom of BAssert.h add the lines

assert(TESTING);
ASSERT(TESTING);

And then from a command line prompt run something like

cl -E bassert.h > bassert.txt

bassert.txt should contain the expanded macro. It doesn't matter that TESTING isn't defined to mean anything. It's just a place holder for the preprocessor to use. Remember that the preprocessor is just a text substitution mechanism. So bassert.txt should contain a line that looks something like this:
if (!TESTING) { cerr << "\nAssertion Failed: " << "TESTING" << "\nFailure occured on line " << __LINE__ << " of source file:" << "\n  \"" << __FILE__ << "\"\n";  };  


Notice the semicolon at the end? looks awkward yes? With macros, special care must be taken to enable using a semi-colon at the end. Typically, this involves using a do-while loop like so

#ifdef _DEBUG#define ASSERT(x) do { if( !(x) ) { DebugBreak(); } } while(0)#else#define ASSERT(x)#endif  


The above would expand to

do { if( !(TESTING) ) { DebugBreak(); } } while(0);

which is legit.

Another thing to note is the parens surrounding the macro parameter. Because the preprocessor macro expansion is a text substitution mechanism - parameters are not passed to it and compound statements can have side effects. For example,

ASSERT( a == b )

produces this

do { if( !(a == b) ) { DebugBreak(); } } while(0);

without those parens, it produces this

do { if( !a == b ) { DebugBreak(); } } while(0);

that's not the same condition!

There's more about using macros in the C faq than the C++ faq. Macros are looked down on in C++.



[edited by - lessbread on March 7, 2003 2:37:54 PM]
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Here is how I would define assert:
#define assert(Expr) _DebugAssert(Expr, #Expr, __FILE__, __LINE__)void _DebugAssert(bool Expr, const char *szExpr, const char File, int Line){     if(!Expr)     {          cout << "Error In File \"" << File << "\" on Line #" << Line << ": " << szExpr << " = " << Expr << endl;         exit(1);     }} 


or something like that (coding style obfuscated to protect the guilty =-)

----------
Almost typo-ified using Extrarius'' AUTOMATIC Typo Generator, but I decided to be nice =-)
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
hmmm...i've used your source extrarius and put it in the following code...


      #include <iostream>using namespace std;#define assert(Expr) _DebugAssert(Expr, #Expr, __FILE__, __LINE__)void _DebugAssert(bool Expr, const char *szExpr, const char File, int Line){     if(!Expr)     {          cout << "Error In File \"" << File << "\" on Line #" << Line << ": " << szExpr << " = " << Expr << endl;          exit(1);     }} int main( void ) {    int x = 0;    assert(x==0);    int y = 1;    assert(y==0);}   

but i get the following two errors:

  c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert2\main.cpp(21): error C2664: '_DebugAssert' : cannot convert parameter 3 from 'char [93]' to 'const char'c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert2\main.cpp(23): error C2664: '_DebugAssert' : cannot convert parameter 3 from 'char [93]' to 'const char'      


thanks in advance.

[edited by - kordova on March 18, 2003 1:15:26 PM]

This topic is closed to new replies.

Advertisement