Thread: Re-Written Assert, can't get __FUNCTION__ or __func__ to work

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    47

    Re-Written Assert, can't get __FUNCTION__ or __func__ to work

    I have re-written assert to serve my own purpose. I want to hide debug implementation details from the "callers" using functions. Basically, a string parameter in my functions will be hidden from them and that string will contain debug information. I want my assert's to do the following:

    1)failed statement, line, file, function
    2)line, file, function (where call originated from)

    This is because my code i need to test is seperate from my "main" application.

    example:

    Code:
    main.c    //origin of call
    int main()
    {
        dosomething();
    }
    Code:
    dosomething.c //where code being tested is
    int dosomething()
    {
       myassert( statement ); //tell me statement, function, line, file (and origin line, file, function)
    }
    Here is what i've come up with, but the __FUNCTION__ or __func__ doesn't expand, it just prints as __FUNCTION__ or __func__.... The following is an example, in the same file but it is only an example!

    Code:
    #define STRINGIFY(x) #x
    #define TOSTRING(x) STRINGIFY(x)
    #define LOCATION  __FILE__ ":" TOSTRING(__LINE__)  //<---I want the __func__ here...
    
    #ifdef NDEBUG
    #define CHECK(ignore)((void) 0)
    #else
    #define CHECK(x)                                                                \
    {                                                                               \
            if( !(x) )                                                              \
            {                                                                       \
                    fprintf(stderr, "%s %s %s", TOSTRING(x), LOCATION, origin );    \
                    exit(1);                                                        \
            }                                                                       \
    }
    #endif
    
    //when caller uses this function, they don't know about the "char *origin" parameter
    void myfunction( char *origin, int index, int value )
    {
            CHECK( index == 2 );
    }
    
    #define myfunction(...) myfunction(LOCATION,__VA_ARGS__) //hide implementation details
    
    int main ()
    {
           myfunction(1,2); //use the same way whether debugging is on or off
    
           return( 0 );
    }
    Thanks in advance..Oh, and the macros __FUNCTION__ etc.. do work on their own if I were to use printf("%s", __FUNCTION__); but that's not what i'm looking for. I would like to append it to my define, thanks.
    Last edited by tempster09; 12-20-2009 at 01:55 PM.

  2. #2
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    This might be better served in the Windows forum since this is not a standard (ANSI) macro expansion. That said a quick Google reveals that this will not expand if the /EP or /P compile option is specified....

    HTH
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Well than how can I do it appropriately for non-windows platforms? I am currently using linux, it is for unix, and I would like it to be portable. How does assert do it?

  4. #4
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    I would have to dig to get an answer since I have never tried this. If I find something I will get back to you...this BTW is any I like adhering to language standards, an opinion not shared by all.

    Later
    J.
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  5. #5
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Have you read this? GCC Function names
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  6. #6
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Is stringification, ... (ellipsis), and __FUNCTION__ C99 compliant? I don't want to be writing code thats gonna crap out across platforms.

    I can simply use __FUNCTION__ in my "ASSERT" define, but than I only get the function where the assertion is firing, not the end of the world, because I will know the file and line number of the originating call. I guess i'm just being picky and looking for as much information as possible. Should i be doing conditional compilation based on compiler present and version etc...?

    The link you pointed me to mentioned compiler version changed from string literal to variable for __FUNCTION__, so than I should be doing conditional compilation on how I append __FUNCTION__ to my define, but i'm still puzzled on how I add it to the define and get it to work properly.
    Last edited by tempster09; 12-20-2009 at 02:36 PM.

  7. #7
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    @Tempster: depends on how many/which platforms you are trying to support as well as compiler (and by extension language versions)....also I wanted to add where I said that the FUNCTION bit was MS-specific, that came right off of the MSDN. I did not know that GCC was trying to support it too. WRT to stringification, let me look when I get my chores done (holiday relatives arriving tomorrow so have meat-space things to get done...meh)
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by tempster09
    Is stringification, ... (ellipsis), and __FUNCTION__ C99 compliant? I don't want to be writing code thats gonna crap out across platforms.
    Yes, dunno (in this context), no (unless I missed something again).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    don't rush, it's the holidays, don't make me a priority lol.

    I'm only working with GCC probably 3.0+, across linux platforms. I think __FUNCTION__ is supported by GCC and expanded to a string literal, and after 3.0 or something it was treated as a variable i.e. __func__.

    printf("%s", __FUNCTION__); gives me what I need for the context of the function that's failing, I just can't get it to work in my Macro (which i want to use on any function), maybe because it isn't defined in that context....i'm not sure but it only gives me the macro itself i.e. "__FUNCTION__" is printed to screen when included in my macro.

    Laserlight: i'm sorry I don't understand your response.

    Basically, i guess i need a way to concatenate two const char *, because __func__ is a variable and Ive already got a string containing the LINE and FILE....

    #define myfunction(...) myfunction(strncat(LOCATION, __func__, strlen(__func__) ), __VA_ARGS__) //Results in an error at memcopy (debugging i see both strings are correct, but i can not read the source file the error occurs at
    Last edited by tempster09; 12-20-2009 at 04:01 PM.

  10. #10
    Registered User jeffcobb's Avatar
    Join Date
    Dec 2009
    Location
    Henderson, NV
    Posts
    875
    Quote Originally Posted by tempster09 View Post
    don't rush, it's the holidays, don't make me a priority lol.
    Yes but as the wise man says "Coding is more fun than mopping floors"
    I'm only working with GCC probably 3.0+, across linux platforms. I think __FUNCTION__ is supported by GCC and expanded to a string literal, and after 3.0 or something it was treated as a variable i.e. __func__.
    It might be helpful to know your *exact* compiler version since according to the link I posted:
    These identifiers are not preprocessor macros. In GCC 3.3 and earlier, in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as string literals; they could be used to initialize char arrays, and they could be concatenated with other string literals. GCC 3.4 and later treat them as variables, like __func__. In C++, __FUNCTION__ and __PRETTY_FUNCTION__ have always been variables.
    Plus I know I don't have any compiler in the house with a version less than 4.x....

    J.
    C/C++ Environment: GNU CC/Emacs
    Make system: CMake
    Debuggers: Valgrind/GDB

  11. #11
    Registered User
    Join Date
    Dec 2009
    Posts
    47
    Ya, my current compiler is at 4.xx as well.

    RE:
    Basically, i guess i need a way to concatenate two const char *, because __func__ is a variable and Ive already got a string containing the LINE and FILE....

    #define myfunction(...) myfunction(strncat(LOCATION, __func__, strlen(__func__) ), __VA_ARGS__) //Results in an error at memcopy (debugging i see both strings are correct, but i can not read the source file the error occurs at

    So im not sure what i'm doing wrong. It seems it just doesn't want to group these strings together, i can pass them as two seperate variables but this should be working
    Last edited by tempster09; 12-20-2009 at 04:06 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Customized assert question...
    By Raigne in forum C++ Programming
    Replies: 10
    Last Post: 02-21-2008, 04:28 AM
  2. The Bludstayne Open Works License
    By frenchfry164 in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 11-26-2003, 11:05 AM
  3. fopen();
    By GanglyLamb in forum C Programming
    Replies: 8
    Last Post: 11-03-2002, 12:39 PM