Why Does Autoconf Erroneously Find a Function Which Isn't Available Later

What does autoconf actually run for the AC_CHECK_FUNCS functionality

It generates a test program that declares a function with the same name, then compiles and link it. Change a few characters in the name of the function (to make the test fail) and check config.log, you'll see the source code of the test program when it fails.

Undefined references in autotools project

riemann-client fails to use

#ifdef __cplusplus
extern "C" {
#endif
...
#ifdef __cplusplus
}
#endif

in its header files, therefore your riemanpp code parts think it is calling C++ code when in fact it is C.
And you cannot just use

#ifdef __cplusplus
extern "C" {
#endif
#include <riemann/event.h>
...

as that could possibly subject C++ headers to be wrongly wrapped into C calling conventions. (Meaning the fix must occur in riemann-client)

C++ macro to test availability of __func__, __FUNCTION__, __PRETTY_FUNCTION__, etc

T.C. supplied this answer first, as a comment under my question, and I ended up basing my solution on it:

The header <boost/current_function.hpp> in Boost.Assert implements a BOOST_CURRENT_FUNCTION macro that attempts to map to a suitable "current function" facility provided by the compiler.

Documentation is here:

http://www.boost.org/doc/libs/1_66_0/libs/assert/doc/html/assert.html#current_function_macro_boost_current_function_hpp

And here is a concise reproduction of the macro for reference:

#if defined( BOOST_DISABLE_CURRENT_FUNCTION )
# define BOOST_CURRENT_FUNCTION "(unknown)"
#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__DMC__) && (__DMC__ >= 0x810)
# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
# define BOOST_CURRENT_FUNCTION __FUNCSIG__
#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500))
# define BOOST_CURRENT_FUNCTION __FUNCTION__
#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550)
# define BOOST_CURRENT_FUNCTION __FUNC__
#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
# define BOOST_CURRENT_FUNCTION __func__
#elif defined(__cplusplus) && (__cplusplus >= 201103)
# define BOOST_CURRENT_FUNCTION __func__
#else
# define BOOST_CURRENT_FUNCTION "(unknown)"
#endif

I ended up modifying the codebase I was working with to use the Boost macro when available, and to fall back to a reasonable subset of the Boost checks otherwise (GCC > MSVC++ > C++11).

Is this a bug in glibc printf?

Is this a bug in glibc printf?

No.

printf("%ld\n", INT32_MIN);2147483648

There is an easy way for this to happen. The second integer/pointer argument to a function should be passed in 64-bit register RCX. INT32_MIN is a 32-bit int with bit pattern 0x80000000, since that is the two’s complement pattern for −2,147,483,648. The rules for passing a 32-bit value in a 64-bit register are that it is passed in the low 32 bits, and the high bits are not used by the called routine. For this call, 0x80000000 was put into the low 32 bits, and the high bits happened to be set to zero.

Then printf examines the format string and expects a 64-bit long. So it goes looking in RCX for a 64-bit integer. Of course, the rules for passing a 64-bit integer are to use the entire register, so printf takes all 64 bits, 0x0000000080000000. That is the bit pattern for +2,147,483,468, so printf prints 2147483648.

Of course, the C standard does not define the behavior, so other things could happen, but this is a likely scenario for what did happen in the instance you observed.

printf("%d\n", INT16_MIN);-32768

Since int is 32 bits in your C implementation, the int16_t value INT16_MIN is automatically promoted to int for the function call, so this passes an int, and %d expects an int, so there is no mismatch, and the correct value is printed.

Similarly, the other printf calls in the question have arguments that match the conversion specifications (given the particular definitions of int16_t and such in your C implementation; they could mismatch in others), so their values are printed correctly.



Related Topics



Leave a reply



Submit