a good testing for a page allocator and malloc/free

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a good testing for a page allocator and malloc/free

Post by Candy »

Solar wrote: One notion on Candy's post:

The assert() macro you get by including [tt]<assert.h>[/tt] does not execute the assertion when NDEBUG is defined. Which means, Candy's code fragment

Code: Select all

#else
#define assert(x) x
is nice, but non-standard. (Standard would be [tt]#define assert(x) ( (void) 0 )[/tt].) If you do non-standard things, consider naming the function / macro in a non-standard way. While persons used to the standard assert() wouldn't put side-effects in there anyway, it's better to play it safe IMHO.
I don't see where this would cause any harm, except for a system that is compiled with this code by somebody who makes a mistake in the assert code and then compiles it on a system that does not do this.

For all purposes it is an assert, with the side note that it does not cause side-effects and it is slightly slower on non-properly-optimizing compilers when building a release without debug code (but then again, if you're going to compile a release, use an optimizing compiler). I honestly don't see where this would cause a problem (except for training new people to comply with the original type of assert - but I don't see the point of that, if you can just use this one instead).
B.E

Re:a good testing for a page allocator and malloc/free

Post by B.E »

I prefer this in my header.

Code: Select all

#ifdef DEBUG
        #define dbg_val(ns) _dbg_assert_val(__FILE__,__LINE__,__func__,#ns,ns);
        #define dbg_msg(msg) _dbg_assert(__FILE__,__LINE__,__func__,msg);
        #define dbg_assert(x) ((x) ? (void)0 : __FILE__,__LINE__,__func__,"ASSERT"#x);
        #define db
#else
        #define dbg_val(ns)
        #define dbg_assert
        #define dbg_msg(msg)
#endif
and this as the implementation

Code: Select all

#include "debug.h"
//////////////////////////////////////////////////
// Purpose: debugging rutiens
// Pre....: file is the name of the file the debugging message came from
//        : Line is the line number the message came from
//        : func is the function the message came from
//        : var is the variable name
//        : val is the value of the variable
// Post...: a message is printed to the stderr
//////////////////////////////////////////////////
void _dbg_assert_val(const char*file,unsigned int Line,const char *func,const char *Var,unsigned int val)
{
           fprintf(stderr,"%s:%d:(%s) %s = %d\n",file,Line,func,Var,val);
}
/////////////////////////////////////////////////

//////////////////////////////////////////////////
// Purpose: debugging rutiens
// Pre....: file is the name of the file the debugging message came from
//        : Line is the line number the message came from
//        : func is the function the message came from
//        : msg is the message to processes
// Post...: a message is printed to the stderr
//////////////////////////////////////////////////
void _dbg_assert(const char * file, unsigned int Line,const char *func, const char * msg)
{
           fprintf(stderr,"%s:%d:(%s) %s\n",file,Line,func,msg);
}
This works in the VIM's compiler error thing (e.g. VIMs :make coomand)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:a good testing for a page allocator and malloc/free

Post by Solar »

Candy wrote: I don't see where this would cause any harm...
Standards fascist and paranoiac, yours truly. ;D

Edit: Then again... I can see where it would cause harm: if careless including happens to mix your [tt]assert()[/tt] with the standard one... but nevermind, I like the first sentence better. ;)
Every good solution is obvious once you've found it.
bkilgore

Re:a good testing for a page allocator and malloc/free

Post by bkilgore »

B.E wrote: I prefer this in my header.
These don't seem to quite be assert's to me. More like debug tracing messages. An assert is usually used to verify that an invariant is true, and to do something (die, display a message, whatever you want depending on implementation) if it is not. Your "assert"s just display a message at that location no matter what.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:a good testing for a page allocator and malloc/free

Post by Solar »

More like an assertion that the program is still running. 8) You're also using DEBUG where <assert.h> uses NDEBUG, and setting DEBUG removes any side effects the macro calls might have from the code.

(Yes I know I've nitpicked Candy for the exact opposite. Isn't it nice when both ways are wrong, somehow? ;D )
Every good solution is obvious once you've found it.
proxy

Re:a good testing for a page allocator and malloc/free

Post by proxy »

the reason why it is very much incorrect to have:

Code: Select all

#define assert(x) x

instead of 

#define assert(x) 
is because statements can have side effects. For example, what if I did something like this:

Code: Select all

assert(func() == 3);
with your version, func() will be called in the non-debug release and in the standard version it wont. This does happen in practice for example in my page manager i have code which lookes like this:

Code: Select all

void releasePage(page_t *p) {
    assert(!inPageStore(p));
    /* return page to page store */
}
the reason why i put the test in an assert is because it is a VERY expensive operation which should never be needed when the code is correct. In a release build this would be a big negative effect but is fine for debug builds.

proxy
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a good testing for a page allocator and malloc/free

Post by Candy »

proxy wrote: ... is because statements can have side effects. For example, what if I did something like this:

Code: Select all

assert(func() == 3);
with your version, func() will be called in the non-debug release and in the standard version it wont. This does happen in practice for example in my page manager i have code which lookes like this:

Code: Select all

void releasePage(page_t *p) {
    assert(!inPageStore(p));
    /* return page to page store */
}
the reason why i put the test in an assert is because it is a VERY expensive operation which should never be needed when the code is correct. In a release build this would be a big negative effect but is fine for debug builds.

proxy
If the function had any side-effect, the code would be different if you made the non-debug function. If it didn't have any side effect, the function should've been declared const (and the optimization would not call it, since the return variable wasn't used). Not entirely sure, but 99%.
proxy

Re:a good testing for a page allocator and malloc/free

Post by proxy »

well sure the code is different in debug builds from release builds, but the standard doesn't say that's not allowed/wrong to do.

Personally my policy is that if i name a function to match part of libc, it will conform completely with the C definition of that to avoid any confusion/misunderstandings about intent.

proxy
Ytinasni

Re:a good testing for a page allocator and malloc/free

Post by Ytinasni »

Candy wrote:If it didn't have any side effect, the function should've been declared const
You cant declare a function const in C. Only in C++ can you do that, and only then on non-static member functions.

(GCC has attribute(pure), which does something similar, but isnt standard.)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a good testing for a page allocator and malloc/free

Post by Candy »

Ytinasni wrote:
Candy wrote:If it didn't have any side effect, the function should've been declared const
You cant declare a function const in C. Only in C++ can you do that, and only then on non-static member functions.

(GCC has attribute(pure), which does something similar, but isnt standard.)
Is that even in C99?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:a good testing for a page allocator and malloc/free

Post by Solar »

@ proxy:
the reason why it is very much incorrect to have:

Code: Select all

#define assert(x) x
instead of

Code: Select all

#define assert(x)
is because statements can have side effects.

[...]

Personally my policy is that if i name a function to match part of libc, it will conform completely with the C definition of that to avoid any confusion/misunderstandings about intent.
The standard says:
If NDEBUG is defined as a macro name at the point in the source file where <assert.h> is included, the assert macro is defined simply as

#define assert(ignore) ((void)0)
Means, yes, it would somehow feel "better" to have the statement executed even if the assertion is "off", but it's not what the standard defines for assert(). Expensive operations being a good reason for this. (Picture, in C++ code, an assert() that constructs an elaborate trace message that includes turning lots of objects into their string representations...)

@ Candy:
Is that even in C99?
I don't know where you got the "const" thing from, but you seem to have it confused with some other language's constructs - neither C nor C++ know something like the kind of "const function" you described. In C++, a "const" function is one you can call on a constant object because it does not modify object state. In C, there is no such thing as a const function unless I'm heavily mistaken.
Every good solution is obvious once you've found it.
proxy

Re:a good testing for a page allocator and malloc/free

Post by proxy »

Solar, not quite sure where you were going with that post since it more or less agrees with my assertion that when NDEBUG is defined, the statement should do nothing....

proxy
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:a good testing for a page allocator and malloc/free

Post by Solar »

I was a bit confused about your meaning, because at first you said "it's bad because side effects won't happen". ;)
Every good solution is obvious once you've found it.
Post Reply