On Tue, Feb 16, 2016 at 10:45 AM, Jonathan Wakely <jwakely@fedoraproject.org> wrote:
On 16/02/16 16:31 +0000, Jonathan Wakely wrote:
On 16/02/16 10:13 -0600, Richard Shaw wrote:
This seems like a pretty basic error in something that has worked fine for
a very long time. Is there anything in the GCC 6 update that would cause
this?

This no longer compiles with GCC 6:

#define max(a, b) (a > b ? a : b)
#include <stdlib.h>
int i = max(0,1);

The reason is that 'max' is used throughout the standard library, and
it's undefined behaviour to define a macro that clashes with any name
defined in the standard library. Previously <stdlib.h> was not
provided by GCC's C++ std::lib, so didn't #undef min and max. Now GCC
provides its own C++-conforming <stdlib.h> and so it does #undef min
and #undef max.

If that's the cause, the code might have been working fine but was
always relying on undefined behaviour.


As I guessed, blender does this:

#ifndef __COMMON_H__
#define __COMMON_H__

#ifndef min
#define min(a,b) ((a) <= (b) ? (a) : (b))
#endif
#ifndef max
#define max(a,b) ((a) >= (b) ? (a) : (b))
#endif
#ifndef clamp
#define clamp(x,a,b) min(max((x), (a)), (b))
#endif

That's undefined behaviour for two separate reasons, yay.

The include guard uses a reserved name containing two underscores,
undefined.

It defines macros "min" and "max", undefined.

It assumes that those macros will remain defined after including
standard library headers, which is not a valid assumption because
standard library headers can assume nobody defines macros with names
that clash with the standard library.

I suggest #include <algorithm> and using std::max;

This will work. Alternatively, #include <stdlib.h> before defining
those macros, so that the library's #undef happens first, and then the
undefined behaviour comes later.

That got it. Thanks for the tip. I have submitted the patch upstream.

Thanks,
RichardÂ