1

I'm using the ATtiny x5 series board, compiling my project (.cpp.ino file). Whenever I use the max(a,b) macro, I receive this message:

"C:\Documents and Settings\<user>\Local Settings\Application Data\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.3-arduino2/bin/avr-g++" -c -g -Os  -std=gnu++11 -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=attiny85 -DF_CPU=8000000L -DARDUINO=10609 -DARDUINO_AVR_ATTINYX5 -DARDUINO_ARCH_AVR   "-IC:\Documents and Settings\<user>\Local Settings\Application Data\Arduino15\packages\ATTinyCore\hardware\avr\1.1.1\cores\tiny" "-IC:\Documents and Settings\<user>\Local Settings\Application Data\Arduino15\packages\ATTinyCore\hardware\avr\1.1.1\variants\tinyX5" "-IC:\Documents and Settings\<user>\My Documents\Arduino\libraries\Pins_xxxxx" "-IC:\Documents and Settings\<user>\My Documents\Arduino\libraries\TinyWireS" "C:\WINDOWS\TEMP\build18f8c74edd63168be814edc24cb0a11a.tmp\sketch\AT85PWM.ino.cpp" -o "C:\WINDOWS\TEMP\build18f8c74edd63168be814edc24cb0a11a.tmp\sketch\AT85PWM.ino.cpp.o"
C:\Documents and Settings\<user>\Local Settings\Application Data\Arduino15\packages\ATTinyCore\hardware\avr\1.1.1\cores\tiny/Arduino.h:54:24: note: in definition of macro 'max'
 #define max(a,b) ((a)>(b)?(a):(b))
                        ^

What does note: in definition of macro 'max' mean, do I need to do anything about it, and if so what?

Searching google for the message gives lots of compiler output listings with the message, but the posting is always for another different message that is causing trouble. None of the fixes from those posts address the max note: message.

  • Is that the only message? Can you please post your code, or at least a Minimal, Complete, and Verifiable example. I suspect it is something to do with the data types being used when you use max in some context. – Nick Gammon Aug 31 '16 at 2:19
  • I spent a good hour trying to package up something small for you before I decided to abort. – HiTechHiTouch Aug 31 '16 at 4:45
  • @Nick, I spent a good hour trying to package up something small for you before I decided to abort. The basic problem seemed to be a function call where MAX was used to calculate one parameter, and a macro was used to try and extract a field from a structure for use as another parameter. Because of C++'s insistence that structs are classes, and therefore a search for explicit conversion routine, the macro used to extract the field gets flagged along with all other macros in the function call. This seems a tad overzealous, but it's better to have too much info... – HiTechHiTouch Aug 31 '16 at 4:53
  • And there's a 5 minute rule about editing comments. Should be more like 30. Some of us are slow thinkers, need to consult references, need time to edit.... Buzzzzzzzzzzz your time is up, next contestant please! – HiTechHiTouch Aug 31 '16 at 4:54
  • I was recently working on another project where I got a similar message. However before it was the real error message/warning. The "note" line just tells you where the macro is defined. The "real" error/warning occurs when the macro is used (because that is where you might have signed/unsigned mismatches, for example). – Nick Gammon Aug 31 '16 at 6:02
2

I can reproduce your message easily enough:

#define max(a,b) ((a)>(b)?(a):(b))

void setup() {
 int b = 66;
 unsigned int c = 42;
 analogWrite (3, max (b, c));
}

void loop() { }

I get these warnings:

/tmp/arduino_modified_sketch_857720/sketch_aug31a.ino: In function 'void setup()':
/tmp/arduino_modified_sketch_857720/sketch_aug31a.ino:1:25: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
 #define max(a,b) ((a)>(b)?(a):(b))
                         ^
/tmp/arduino_modified_sketch_857720/sketch_aug31a.ino:6:18: note: in expansion of macro 'max'
  analogWrite (3, max (b, c));

The point is that the warning note: in expansion of macro 'max' is just telling you where the macro is defined, so you can make sense of the real warning. The real warning is: warning: comparison between signed and unsigned integer expressions

So, reading them together, you are comparing (in the macro) a signed and unsigned number, and the compiler is warning you about that.

The message seems like a red herring, given that there is no problem with the max(a,b) macro definition. I suspect it is being flagged only because it was tangentially involved with a statement in error.

That's right. There is no problem in that macro per se. Macros can generate weird error message because they are just text replacements. For example:

max (the quick brown fox, jumps over the lazy dog);

That will generate a slew of errors, including a "note" to where max is defined. There is nothing wrong with max until you try feeding garbage into it.


Templates

That's one of the reasons I prefer to avoid macros if possible. You can do "max" with a template. For example:

#undef max   // throw away the original macro in the Arduino header file

template<typename T> T max (T a, T b)
  {
  if (a > b)
    return a;

  return b;
  }

Now you get slightly more reasonable error messages:

/tmp/arduino_modified_sketch_711186/sketch_aug31a.ino: In function 'void setup()':
sketch_aug31a:14: error: no matching function for call to 'max(int&, unsigned int&)'
   analogWrite (3, max (b, c));
                            ^
/tmp/arduino_modified_sketch_711186/sketch_aug31a.ino:14:28: note: candidate is:
/tmp/arduino_modified_sketch_711186/sketch_aug31a.ino:3:24: note: template<class T> T max(T, T)
 template<typename T> T max (T a, T b)
                        ^
/tmp/arduino_modified_sketch_711186/sketch_aug31a.ino:3:24: note:   template argument deduction/substitution failed:
/tmp/arduino_modified_sketch_711186/sketch_aug31a.ino:14:28: note:   deduced conflicting types for parameter 'T' ('int' and 'unsigned int')
   analogWrite (3, max (b, c));
                            ^
exit status 1
no matching function for call to 'max(int&, unsigned int&)'

Of course, now you've gone from a warning to an error, because the template wants a single type.

Notice the notes? That's just the compiler trying to be helpful.


You could make the template take two types if you are prepared to guess the return type (will it be the first type, or the second type?):

#undef max

template<typename T1, typename T2> T1 max (T1 a, T2 b)
  {
  if (a > b)
    return a;

  return b;
  }

Now you don't get an error or a warning, however the result will be the first type (T1) which may or may not suit you.

  • Twasn't the case. You constructed an example were the max() macro operands were in error. In my case, the max() macro operands were just fine, and the relevant diagnostics involved another macro. max() wasn't part of the expression in error. – HiTechHiTouch Sep 1 '16 at 13:16
  • Regarding templates: the max() macro comes with the Arduino IDE base. Perhaps you would be in a better position than I to get the IDE to change over to templates. – HiTechHiTouch Sep 1 '16 at 13:18
  • you would be in a better position than I to get the IDE to change over to templates - If they were to do that, it would probably throw up heaps of warnings, or even errors, in code that currently compiles with only a warning. So they probably won't. max() wasn't part of the expression in error - yes, well I would like to see this reproduced before I could agree. – Nick Gammon Sep 1 '16 at 21:38
  • the relevant diagnostics involved another macro - it would help to post all the diagnostics, and not just the ones involving max. Plus the defines for this other macro, and the lines of code which produced the error. – Nick Gammon Sep 1 '16 at 21:39
1

Note to the future:

(My particular case was a function call with several parameters. One had the max(a,b), and another parameter had an error. It used a different macro, which may have pushed the compiler to flag every macro in the whole call).

The message seems like a red herring, given that there is no problem with the max(a,b) macro definition. I suspect it is being flagged only because it was tangentially involved with a statement in error.

Since it wasn't part of the problem, the compiler couldn't say anything specific about it or the code it generated. Therefore the flagging message then ends up saying "in definition of macro" (kind of a default of last resort) since it couldn't say anything more specific.

If you ever get one of these, particularly from a system provided macro, ignore it until you've diagnosed your other problems.

Ignore the fact that the error message is first in the listing, and the statement using the macro doesn't get flagged until after several other statements are flagged.

Again, I suspect that compiler feels obligated to say something about the macro because it was used. But since it's not part of the problem in the statement where it appears, it doesn't get flagged there. Instead the compiler puts the message at the top because it has to go somewhere, but the compiler can't/doesn't want to associate it with the statement where it was used.

The solution worked for me, but a language lawyer or compiler developer may say my explanation has no basis.

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.