1

I have written my own 'assert' since I want to use it for both Windows and Arduino. The class is called from many files (about 10).

AssertUtils.h:

#pragma once

#define assert(expr) AssertUtils::Assert2((expr), (__func__), (__FILE__), (__LINE__));

class AssertUtils
{
public:
    static void Assert2(bool expression, const char* funcName, const char* fileName, int line);
};

AssertUtils.cpp:

#include "AssertUtils.h"
#include "Arduino.h"

/* static */ void AssertUtils::Assert2(bool expression, const char* funcName, const char* fileName, int line)
{
    if (!expression)
    {
        Serial.println(funcName);
        Serial.println(fileName);
        Serial.println(line, DEC);
        Serial.flush();

        // Abort program execution.
        abort();
    }
}

When I compile this, the SRAM usage is 1469 bytes (together with the rest of my sketch and classes).

When I comment the line below, I get a segmentation fault in a random assert call (when I comment out that call, I get it in the next, etc.).

    //Serial.println(funcName);

When I also comment out the second print statement, the compiler reports only 1137 bytes SRAM usage (which I expect since this was about equal until before I added the Assert class).

    //Serial.println(funcName);
    //Serial.println(fileName);

Questions:

  1. How can I get rid of the segmentation fault?
  2. How can it be that about 332 bytes are used for one two additional print statements? (maybe related to the const char* buffering (?)
  • 1
    the segmentation fault is a bug in compiler in 1.6.22 and 1.6.23. more here forum.arduino.cc/index.php?topic=619213.msg4195749#msg4195749 – Juraj Jun 2 at 16:00
  • 1
    try F(__FILE__) and F(__func__). (change the parameter type to __FlashStringHelper) – Juraj Jun 2 at 16:03
  • 1
    @Juraj Somehow it only works for __FILE__ but not for __func__. Anyway using F( __FILE__) was about -90B difference (It's probably full path and it was only used in one file). – KIIV Jun 2 at 16:32
  • 1
    so the compiler optimizes the parameters away if hey are not used – Juraj Jun 2 at 17:49
  • 1
    Why are you wasting a class on this? Just use the prints directly in the macro. – Majenko Jun 2 at 18:48
2

Note, this answer is not MY answer, but approximately the combination of the first 5 comments from my original question.

What I did was:

  • (Juraj) Changed the compiler version to 6.21
  • (juraj) Added an F in F(__FILE__)
  • (KIIV) Removed func; this did not work with the F flash helper, but I can find back the code anyway unambiguously because of the file name + line number.
  • (Majenko) I removed the class and use a macro. This costs some more Flash memory (depending on the number of asserts I use, but I'm still around 40% (was 35%).

The SRAM usage is now 1125 bytes, even less than where I'm started with.

The resulting code is below:

#define assert(expression) \
  if (!(expression)) \
  { \
    Serial.println(F(__FILE__)); \
    Serial.println(__LINE__, DEC); \
    Serial.flush(); \
    abort(); \
  }
  • 1
    About class - in this case it was used as old form of namespaces (as namespaces weren't present in c++ until 1990). However struct was used more likely as it doesn't need public: specifier. – KIIV Jun 2 at 20:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.