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-gcc4円.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\avr1円.1.1\cores\tiny" "-IC:\Documents and Settings\<user>\Local Settings\Application Data\Arduino15\packages\ATTinyCore\hardware\avr1円.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\avr1円.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.
2 Answers 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– HiTechHiTouch2016年09月01日 13:16:22 +00:00Commented Sep 1, 2016 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– HiTechHiTouch2016年09月01日 13:18:14 +00:00Commented Sep 1, 2016 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.2016年09月01日 21:38:11 +00:00Commented Sep 1, 2016 at 21:38 -
the relevant diagnostics involved another macro
- it would help to post all the diagnostics, and not just the ones involvingmax
. Plus the defines for this other macro, and the lines of code which produced the error.2016年09月01日 21:39:49 +00:00Commented Sep 1, 2016 at 21:39
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.
max
in some context.