Archived

This topic is now archived and is closed to further replies.

kordova

Problem creating own assert()

Recommended Posts

kordova    140
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]

Share this post


Link to post
Share on other sites
LessBread    1415
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

Share this post


Link to post
Share on other sites
Neophyte    595
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

Share this post


Link to post
Share on other sites
kordova    140
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 constant
c:\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 constant
c:\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 identifier
c:\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 break
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(70): error C2046: illegal case
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(72): error C2043: illegal break
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(73): error C2046: illegal case
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(75): error C2043: illegal break
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(76): error C2046: illegal case
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(78): error C2043: illegal break
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(79): error C2047: illegal default
c:\Documents and Settings\Brandon\My Documents\Visual Studio Projects\BRN\MyAssert\main.cpp(81): error C2065: ''assert'' : undeclared identifier
c:\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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
kordova    140
Ah, sweet .net...

I removed all spaces and \''s (put it all on one line basically) and I''ve gotten the same errors... :-\

Share this post


Link to post
Share on other sites
LessBread    1415
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]

Share this post


Link to post
Share on other sites
Extrarius    1412
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 =-)

Share this post


Link to post
Share on other sites
kordova    140
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]

Share this post


Link to post
Share on other sites
kordova    140
Hmmm. Does anyone have a solution that will work? I''ve looked around and I really can''t seem to find an answer aside from those recommendations here.

[edited by - ChildOfKordova on October 11, 2017 10:32:23 AM]
weird

Share this post


Link to post
Share on other sites
Code-Junkie    122
See what happens if you change the third parameter by removing "const". It seems to be the cause of your error message.

Good Luck
Code-Junkie

[edited by - Code-Junkie on April 4, 2003 11:02:05 AM]

Share this post


Link to post
Share on other sites
kordova    140
I tried removing either const and both consts but I still receive the same error message. Curses. Thanks though.

[edited by - ChildOfKordova on October 11, 2017 10:32:23 AM]
weird

Share this post


Link to post
Share on other sites
morebeer    122
i don''t know about your problems with your code, but instead of

exit(1);

i''d do something like

__asm int 3

so you break right into the debugger and see the callstack etc.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
My favourite, PORTABLE, way of generating a run-time break point is:

inline void break() {
*(long *)0 = 0;
}

On older versions of DOS and MacOS classic, this won''t break, but on systems in commercial use today, it will. Most importantly: it will break the same on Windows and Unix, which really are the only two systems that matter anymore. (MacOS X now counts as Unix)

Share this post


Link to post
Share on other sites
kordova    140
For some reason I am confused by this (must be lack of caffeine...)... when exactly would you use that?

[edited by - ChildOfKordova on October 11, 2017 10:32:23 AM]
weird

Share this post


Link to post
Share on other sites
Fruny    1658
kordova - preprocessor macros are looked down because

a) they do not respect scope
b) they do not guarantee single-evaluation of their parameters
c) they are invisible to the compiler which will report an error in the 'expanded' code, not in the original macro

As such, they can cause a number of nasty bugs.

Here's an article about making a fancy assert. Enjoy.

Edit: The AP's code triggers a segmentation fault as he is dereferencing a null pointer.


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on April 5, 2003 6:55:24 PM]

Share this post


Link to post
Share on other sites
Kippesoep    892

  
void _DebugAssert(bool Expr, const char *szExpr, const char File, int Line)
should be:
void _DebugAssert(bool Expr, const char *szExpr, const char *File, int Line)




Share this post


Link to post
Share on other sites
Fruny    1658
quote:
Original post by Kippesoep
void _DebugAssert(bool Expr, const char *szExpr, const char *File, int Line)



Names starting with an underscore and a capital letter are expressely off-limits to user code at global scope.

Names with two underscores anywhere are expressely off-limits at any scope.



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]

Share this post


Link to post
Share on other sites