1

For debugging Matlab-MEX, which can be quite a hassle, it would be nice to have better assertion capabilities. Following this question about mex-assertions, it is possible to define a preprocessor makro, that throws an error to Matlab and prints a string (can mostly replace mxAssert, which unfortunately crashes Matlab2011b).

#define myassert( isOK,astr )      ( (isOK) ? (void)0 : (void) mexErrMsgTxt(astr) ) 

It would be much nicer to print the file, line number and caller function, from where following example assertion myassert(A=B,"A not B") is raised! This answer to the initial question states that they are the preprocessor variables:

__LINE__,__PRETTY_FUNCTION__, __FILE__

How can we print these preprocessor variables with mexErrMsgTxt?

The problem is, that mexErrMsgTxt() takes a char* argument and not multiple inputs like for example printf(const char *format, ...).

My thinking goes only so far at the moment:

  1. It's not possible to build a function, because the preprocessor variables will have the values (e.g. line number) from the function.
  2. It was not possible for me to write a working multiline preprocessor makro that creates a char from the passed string astr and passes it to mexErrMsgTxt(). Maybe a solution is along these lines.
  3. A hybrid solution with a char creating preprocessor makro and a function that passes it to mexErrMsgTxt() doesn't feel like good coding practice.

It would be really nice to make the specified error string optional.

1 Answer 1

3

Concatenating preprocessor tokens works as long as you only use __FILE__, __LINE__ and a string literal as message. Then you can write something like

#define STRINGIZE_I(x) #x
#define STRINGIZE(x) STRINGIZE_I(x)

#define myassert(isOK, astr) ( (isOK) ? (void)0 : (void) mexErrMsgTxt(__FILE__ ":" STRINGIZE(__LINE__) ": " astr) )

Unfortunately, __PRETTY_FUNCTION__ is not a string literal even for those compilers who support it. If you want to use it (or less fixed error messages), you'll have to assemble the string dynamically, which means something along the lines of

#define myassert(isOK, astr)                                            \
  do {                                                                  \
    if(!(isOk)) {                                                       \
      std::ostringstream fmt;                                           \
      fmt << "In " << __PRETTY_FUNCTION__ << ", "                       \
          << __FILE__ << ":" << __LINE__ << ": " << (astr);             \
      (void) mexErrMsgTxt(fmt.str().c_str());                           \
    }                                                                   \
  } while(false)

For C, do the same with snprintf. (Or asprintf. It avoids problems with fixed buffer lengths and long error messages, and it is about as portable as __PRETTY_FUNCTION__). Either way, roughly like

#define myassert(isOK, astr)                                            \
  do {                                                                  \
    if(!(isOk)) {                                                       \
      char buf[ENOUGH_SPACE];                                           \
      snprintf(buf, ENOUGH_SPACE, "In %s, %s:%d: %s",                   \
               __PRETTY_FUNCTION__, __FILE__, __LINE__, (astr));        \
      buf[ENOUGH_SPACE - 1] = '\0';                                     \
      (void) mexErrMsgTxt(buf);                                         \
    }                                                                   \
  } while(0)

...where ENOUGH_SPACE would have to be defined appropriately (in the snprintf case).

2
  • Thank's for that large answer! ;) The string is optional already... Is the (void) command in front of mexErrMsgTxt and in front of 0 really necessary? Or is it just coding practice to clarify that there is no output?
    – JaBe
    Commented Feb 20, 2015 at 15:36
  • 1
    mexErrMsgTxt returns void, and both result operands of ?: have to have the same type, so it's necessary in this construct (which I cargo-culted from the question). As for coding practice: If I had written it myself, I'd have used do { if(!(isOk)) { mexErrMsgTxt(all that stuff); } } while(0) because of stackoverflow.com/questions/154136/…
    – Wintermute
    Commented Feb 20, 2015 at 15:46

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