What does abort() do?

In which case, this may be helpful...
http://www.nongnu.org/avr-libc/user-manual/group__avr__assert.html

It could ... but I don't have the slightest idea of how to direct stderr to the serial ... so why bother adding this layer of complexity?
No, seriously, how may I define __ASSERT_USE_STDERR ? Do I get to redirect it to the serial channel? How?

Anyway, I find usefull that I can disable the assert() when I'm finished debugging, by simply defining NDEBUG once and for all.
That's cool to know :slight_smile:

robitabu:
In this case I'm going to use abort() in a preliminary stage of the coding.

It's already been explained to you that calling abort() under any circumstances in an Arduino sketch is a bad idea. If you want the sketch to chop itself off at the ankles, you could use the while(1); that Coding Badly showed you. Personally I think doing that just because of duff input is probably a cop-out, but if you can't be bothered to do anything more user-friendly then it's a legitimate way to halt your sketch. Calling abort() is not.

...but I don't have the slightest idea of how to direct stderr to the serial...

If you do nothing special...

#include <assert.h>

void setup( void )
{
  assert( false );
}

void loop( void )
{
}

abort is called if the assertion fails. stderr does not come into the picture.

[quote author=Coding Badly link=topic=144756.msg1087551#msg1087551 date=1359071251]If you do nothing special...

#include <assert.h>

void setup( void )
{
  assert( false );
}

void loop( void )
{
}

abort is called if the assertion fails. stderr does not come into the picture.[/quote]

That's all clear to me. That's how I already used it after you suggested it to me.
But ... that way, it does no more than calling abort(), right? Why should I even bother with calling assert() then? What's the point if it does'nt add anything new to the picture?

You can disable it with the #define. Just a few posts up you said that was a good thing. 8^)

But now that it has been brought up, is there any way to redirect stderr to Serial, and then enable with #define __ASSERT_USE_STDERR , like int std c++ you could do

std::cerr.rdbuf(myOStream.rdbuf());

?

johncc:
But now that it has been brought up, is there any way to redirect stderr to Serial,

Yes, there is. You can associate stdin, stdout and stderr with the hardware Serial if you want (or any other device) by writing put and get functions for the device and then associating these functions with each stream by calls to fdevopen().

That's the most interesting piece of information I have seen all week.

robitabu:
Why should I even bother with calling assert() then?

Welcome to "Design by Contract" ... Design by contract - Wikipedia ... I highly recommend Bertrand Meyer's book.

robitabu:
What does actually abort() do in Arduino?

From stdlib.h:

/** The abort() function causes abnormal program termination to occur.
    This realization disables interrupts and jumps to _exit() function
    with argument equal to 1. In the limited AVR environment, execution is
    effectively halted by entering an infinite loop. */
extern void abort(void) __ATTR_NORETURN__;

A simple error handler could be:

if (somethingBadHappens)
  {
  Serial.println (F("Bad thing XYZ happened."));
  Serial.flush ();
  exit (1);
  }

The flush call will ensure the message appears before you go into the infinite loop. The F macro saves wasting valuable RAM on the message.

To ensure there is no ambiguity, I strongly agree with @PeterH...

It is never appropriate to use the AVR Libc abort.

Actually I got bitten in one of my libraries because exit() isn't always implemented. This might be neater:

if (somethingBadHappens)
  {
  Serial.println (F("Bad thing XYZ happened."));
  Serial.flush ();
  noInterrupts ();
  while (true) { }   // give up
  }

This should get you started...

#define __ASSERT_USE_STDERR
#include <assert.h>

extern void __assert(
    const char *__func, 
    const char *__file,
    int __lineno, 
    const char *__sexp )
{
  // Put your stuff here.
  // __func is the function name (setup)
  // __file is the module name (the name of your sketch)
  // __lineno is the source code line number of the assert
  // __sexp is the assert expression (as a C string)

  Serial.print( F( "ASSERT FAILURE: " ) );
  Serial.print( __file );
  Serial.print( F( ": " ) );
  Serial.print( __func );
  Serial.print( F( ": #" ) );
  Serial.print( __lineno );
  Serial.println();
  Serial.flush ();
  noInterrupts ();
  while (true) { }   // give up
}

void setup( void )
{
  assert( false );
}

void loop( void )
{
}

Bear in mind that each assert puts up to three string constants in SRAM. A better version would keep the string constants in Flash.

Silly me, I thought I'd need an underlying OS to abort to!
But then when I write code, I expect users to make the occasional error... since 1980.

Look on the bright side. Users expect programmers to make the occasional error, too. :slight_smile:

Users expect programmers to make the occasional error, too.

And I never disappoint them.

From the OLD (it was old in 85) Programmer's Joke Sheet:

Users should not complain about the code they get. They are lucky to get anything at all.

1980 is when I started writing programs for engineers. Error handling became a must!

GoForSmoke:
Users should not complain about the code they get. They are lucky to get anything at all.

Priceless!!! :smiley: