Does anyone have a macro to implement assertions?
#include <assert.h>
void setup ()
{
Serial.begin (115200);
assert (1 == 2);
Serial.println ("assertion passed.");
}
void loop () {}
Uh, thanks Nick. That's the most confusing .h file I've ever tried to figure out.
On my machine the failed case produces some kind of garbage on the serial port and then locks up (as it should).
Are you supposed to be able to include a message in the assert?
Here's what I'm doing...
#include <assert.h>
void setup ()
{
Serial.begin (9600);
Serial.println("testing");
assert (1 == 1);
Serial.println ("assertion passed.");
assert (1 == 2);
// Serial.println (" false assertion passed.");
}
void loop () {}
The fail case drives the serial monitor crazy and chops off everything after the first two letters on the screen, "te." If I comment out the second assert everything works as expected.
Yes the .h file is a shocker.
As for the garbage, the serial output is done by interrupts, and abort() turns off interrupts. So that is pretty-much expected behaviour. I'm not sure of the best way of seeing the error message. Perhaps some sort of check that the serial output buffer has emptied. Or just delay(1000).
If you debug via SPI as suggested here:
... then the debugging messages will have gone before you lock up.
Of course you could write your own assert macro easily enough. After all it's basically an if test, and don't proceed if it fails.
If you don't need dynamic asserts, here is a compile time assert.
If an assertion occurs, your code won't compile and the assertion message is echoed to the IDE output. ( good for validating library inputs )
#define CONCAT_TOKENS( TokenA, TokenB ) TokenA ## TokenB
#define EXPAND_THEN_CONCAT( TokenA, TokenB ) CONCAT_TOKENS( TokenA, TokenB )
#define ASSERT( Expression ) enum{ EXPAND_THEN_CONCAT( ASSERT_line_, __LINE__ ) = 1 / !!( Expression ) }
#define ASSERTM( Expression, Message ) enum{ EXPAND_THEN_CONCAT( Message ## _ASSERT_line_, __LINE__ ) = 1 / !!( Expression ) }
use like
ASSERT( 1 == 1 );
//or
ASSERTM( 1 == 2, Assertion_Failed );
Just do your own, or trick the assertion code to call your assert code rather than abort().
To call your own,
#define __ASSERT_USE_STDERR // do this before including assert.h
#include <assert.h>
Then create a function called __assert()
like this:
__assert (const char *func, const char *file, int line, const char *failedexpr)
{
// print out whatever you like here, function name, filename, line#, expression that failed.
abort(); // halt after outputting information
}
You can then output the information anyway you like.
Here is the original AVR libc __assert() code:
__assert (const char *func, const char *file, int line, const char *failedexpr)
{
if (func == NULL)
(void)fprintf(stderr,
"Assertion failed: (%s), file %s, line %d.\n", failedexpr,
file, line);
else
(void)fprintf(stderr,
"Assertion failed: (%s), function %s, file %s, line %d.\n",
failedexpr, func, file, line);
abort();
/* NOTREACHED */
}
--- bill
It seems that the example of static assert macro from pYro_65 doesn't work for me.
#define CONCAT_TOKENS( TokenA, TokenB ) TokenA ## TokenB
#define EXPAND_THEN_CONCAT( TokenA, TokenB ) CONCAT_TOKENS( TokenA, TokenB )
#define ASSERT( Expression ) enum{ EXPAND_THEN_CONCAT( ASSERT_line_, __LINE__ ) = 1 / !!( Expression ) }
#define ASSERTM( Expression, Message ) enum{ EXPAND_THEN_CONCAT( Message ## _ASSERT_line_, __LINE__ ) = 1 / !!( Expression ) }
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
ASSERT( 1 == 1 );
Serial.println("start");
//or
ASSERTM( 1 == 2, Assertion_Failed );
}
void loop() {
// put your main code here, to run repeatedly:
Serial.println("next");
}
returns failure
Arduino: 1.6.5 (Windows 7), Vývojová deska: "Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"
F:\programs_x86\arduino-1.6.5\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10605 -DARDUINO_AVR_PRO -DARDUINO_ARCH_AVR -IF:\programs_x86\arduino-1.6.5\hardware\arduino\avr\cores\arduino -IF:\programs_x86\arduino-1.6.5\hardware\arduino\avr\variants\eightanaloginputs F:_personal\arduino_out\test_151018.cpp -o F:_personal\arduino_out\test_151018.cpp.o
test_151018.ino: In function 'void setup()':
test_151018.ino:4:114: error: '(1 / 0)' is not a constant expression
test_151018.ino:14:2: note: in expansion of macro 'ASSERTM'
test_151018.ino:4:131: error: enumerator value for 'Assertion_Failed_ASSERT_line_14' is not an integer constant
test_151018.ino:14:2: note: in expansion of macro 'ASSERTM'
'(1 / 0)' is not a constant expression
For a complete code sample using <assert.h> please see this link:
I found this thread and this github post today and found both useful.