Discussion:
how to test for a prototype difference
Thomas Klausner
2014-05-01 00:12:45 UTC
Permalink
Hi!

I found out that the prototypes for backtrace() and backtrace_symbol()
differ on some operating systems.

These are the same:

Linux:
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

Mac OS X:
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void* const* array, int size, int fd);

SunOS:
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *buffer, int size);
void backtrace_symbols_fd(void *const *buffer, int size, int fd);

This one's different:

NetBSD:
size_t backtrace(void **addrlist, size_t len);
char **backtrace_symbols(void * const *addrlist, size_t len);
int backtrace_symbols_fd(void * const *addrlist, size_t len, int fd);

The main difference is that on NetBSD, size_t is used for most
arguments that are int on the other systems; also,
backtrace_symbols_fd returns an int.

I'd like to test for the difference int <-> size_t in a configure
script so I can get integer type/sign conversion-warnings free code on
all these operating systems.

I'm however not sure how to do this. Does anyone have a suggestion?

Thanks,
Thomas
Eric Blake
2014-05-01 00:51:23 UTC
Permalink
Post by Thomas Klausner
Hi!
I found out that the prototypes for backtrace() and backtrace_symbol()
differ on some operating systems.
The main difference is that on NetBSD, size_t is used for most
arguments that are int on the other systems; also,
backtrace_symbols_fd returns an int.
I'd like to test for the difference int <-> size_t in a configure
script so I can get integer type/sign conversion-warnings free code on
all these operating systems.
I'm however not sure how to do this. Does anyone have a suggestion?
Yep - use function pointer assignment or redeclaration to force the
compiler to complain if the redeclaration used the wrong type. Gnulib
has some examples; here's one with ioctl(), which on Linux takes an
'unsigned long' instead of the POSIX 'int' for the second parameter:

AC_CACHE_CHECK([for ioctl with POSIX signature],
[gl_cv_func_ioctl_posix_signature],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/ioctl.h>]],
[[extern
#ifdef __cplusplus
"C"
#endif
int ioctl (int, int, ...);
]])
],
[gl_cv_func_ioctl_posix_signature=yes],
[gl_cv_func_ioctl_posix_signature=no])
])
if test $gl_cv_func_ioctl_posix_signature != yes; then
REPLACE_IOCTL=1
fi

Or this one originally from gettext (but annoyingly encroaching on
automake's namespace), checking whether iconv() uses a const or not:

AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL([am_cv_proto_iconv], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char *
*outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
]],
[[]])],
[am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
am_cv_proto_iconv="extern size_t iconv (iconv_t cd,
$am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char *
*outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e
's/( /(/'`
AC_MSG_RESULT([
$am_cv_proto_iconv])
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
[Define as const if the declaration of iconv() needs const.])

Hopefully that gives you some ideas.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Philip Herron
2014-05-01 08:40:03 UTC
Permalink
Awh cool thanks for sharing that i couldn't figure out how to do this
with something in work.
Post by Eric Blake
Post by Thomas Klausner
Hi!
I found out that the prototypes for backtrace() and backtrace_symbol()
differ on some operating systems.
The main difference is that on NetBSD, size_t is used for most
arguments that are int on the other systems; also,
backtrace_symbols_fd returns an int.
I'd like to test for the difference int <-> size_t in a configure
script so I can get integer type/sign conversion-warnings free code on
all these operating systems.
I'm however not sure how to do this. Does anyone have a suggestion?
Yep - use function pointer assignment or redeclaration to force the
compiler to complain if the redeclaration used the wrong type. Gnulib
has some examples; here's one with ioctl(), which on Linux takes an
AC_CACHE_CHECK([for ioctl with POSIX signature],
[gl_cv_func_ioctl_posix_signature],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[#include <sys/ioctl.h>]],
[[extern
#ifdef __cplusplus
"C"
#endif
int ioctl (int, int, ...);
]])
],
[gl_cv_func_ioctl_posix_signature=yes],
[gl_cv_func_ioctl_posix_signature=no])
])
if test $gl_cv_func_ioctl_posix_signature != yes; then
REPLACE_IOCTL=1
fi
Or this one originally from gettext (but annoyingly encroaching on
AC_MSG_CHECKING([for iconv declaration])
AC_CACHE_VAL([am_cv_proto_iconv], [
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <stdlib.h>
#include <iconv.h>
extern
#ifdef __cplusplus
"C"
#endif
#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus)
size_t iconv (iconv_t cd, char * *inbuf, size_t *inbytesleft, char *
*outbuf, size_t *outbytesleft);
#else
size_t iconv();
#endif
]],
[[]])],
[am_cv_proto_iconv_arg1=""],
[am_cv_proto_iconv_arg1="const"])
am_cv_proto_iconv="extern size_t iconv (iconv_t cd,
$am_cv_proto_iconv_arg1 char * *inbuf, size_t *inbytesleft, char *
*outbuf, size_t *outbytesleft);"])
am_cv_proto_iconv=`echo "[$]am_cv_proto_iconv" | tr -s ' ' | sed -e
's/( /(/'`
AC_MSG_RESULT([
$am_cv_proto_iconv])
AC_DEFINE_UNQUOTED([ICONV_CONST], [$am_cv_proto_iconv_arg1],
[Define as const if the declaration of iconv() needs const.])
Hopefully that gives you some ideas.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
_______________________________________________
Autoconf mailing list
https://lists.gnu.org/mailman/listinfo/autoconf
Thomas Klausner
2014-05-16 00:33:02 UTC
Permalink
Hi Eric!
Post by Eric Blake
Post by Thomas Klausner
Hi!
I found out that the prototypes for backtrace() and backtrace_symbol()
differ on some operating systems.
The main difference is that on NetBSD, size_t is used for most
arguments that are int on the other systems; also,
backtrace_symbols_fd returns an int.
I'd like to test for the difference int <-> size_t in a configure
script so I can get integer type/sign conversion-warnings free code on
all these operating systems.
I'm however not sure how to do this. Does anyone have a suggestion?
Yep - use function pointer assignment or redeclaration to force the
compiler to complain if the redeclaration used the wrong type. Gnulib
has some examples; here's one with ioctl(), which on Linux takes an
Thanks for the idea and the examples!

Here's what I came up with:
AC_CACHE_CHECK([parameter type for backtrace()],
[am_cv_proto_backtrace_type],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <execinfo.h>
extern
#ifdef __cplusplus
"C"
#endif
size_t backtrace(void **addrlist, size_t len);
]])
],
[am_cv_proto_backtrace_type=size_t],
[am_cv_proto_backtrace_type=int])
])
AC_DEFINE_UNQUOTED([backtrace_t], [$am_cv_proto_backtrace_type],
[Define to return type for backtrace().])


It seems to work fine on NetBSD, OS X, and Linux.

This way I can define my variables

backtrace_t len;

and it'll work even if I don't have any backtrace() functionality.

Cheers,
Thomas
Nick Bowler
2014-05-16 15:19:58 UTC
Permalink
Hello,

Some comments...
Post by Thomas Klausner
Hi Eric!
[...]
Post by Thomas Klausner
Post by Thomas Klausner
I'd like to test for the difference int <-> size_t in a configure
script so I can get integer type/sign conversion-warnings free code on
all these operating systems.
I'm however not sure how to do this. Does anyone have a suggestion?
[...]
Post by Thomas Klausner
AC_CACHE_CHECK([parameter type for backtrace()],
[am_cv_proto_backtrace_type],
The am_cv_ prefix is used by Automake so I suggest choosing a
different one.
Post by Thomas Klausner
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <execinfo.h>
extern
#ifdef __cplusplus
"C"
#endif
size_t backtrace(void **addrlist, size_t len);
]])
],
[am_cv_proto_backtrace_type=size_t],
[am_cv_proto_backtrace_type=int])
So if the compilation fails for any reason, you set the type to int.
That could be OK in your case (depending how you use it) but it seems
a little weird to me.
Post by Thomas Klausner
])
AC_DEFINE_UNQUOTED([backtrace_t], [$am_cv_proto_backtrace_type],
[Define to return type for backtrace().])
Note that POSIX reserves identifiers ending in _t if you include any
header file, so you should normally avoid using that suffix in an
application.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Thomas Klausner
2014-05-17 17:07:02 UTC
Permalink
Post by Nick Bowler
Some comments...
Thanks.
Post by Nick Bowler
Post by Thomas Klausner
Hi Eric!
[...]
Post by Thomas Klausner
Post by Thomas Klausner
I'd like to test for the difference int <-> size_t in a configure
script so I can get integer type/sign conversion-warnings free code on
all these operating systems.
I'm however not sure how to do this. Does anyone have a suggestion?
[...]
Post by Thomas Klausner
AC_CACHE_CHECK([parameter type for backtrace()],
[am_cv_proto_backtrace_type],
The am_cv_ prefix is used by Automake so I suggest choosing a
different one.
What do you suggest using as prefixes?
Post by Nick Bowler
Post by Thomas Klausner
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <execinfo.h>
extern
#ifdef __cplusplus
"C"
#endif
size_t backtrace(void **addrlist, size_t len);
]])
],
[am_cv_proto_backtrace_type=size_t],
[am_cv_proto_backtrace_type=int])
So if the compilation fails for any reason, you set the type to int.
That could be OK in your case (depending how you use it) but it seems
a little weird to me.
I have a separate backtrace() test before that:

AC_SEARCH_LIBS([backtrace], [execinfo], [
AC_DEFINE([HAVE_BACKTRACE], [1], [Define to 1 if you have the `backtrace' function.])
], [])

I could make the backtrace type test have three results, int, size_t,
and FAILED, but I'm not sure if it really would serve a purpose. What
kind of errors do you expect?
Post by Nick Bowler
Post by Thomas Klausner
])
AC_DEFINE_UNQUOTED([backtrace_t], [$am_cv_proto_backtrace_type],
[Define to return type for backtrace().])
Note that POSIX reserves identifiers ending in _t if you include any
header file, so you should normally avoid using that suffix in an
application.
Ok, thanks for the note. Suggestions on how to improve it?
Thomas
Eric Blake
2014-05-19 14:14:11 UTC
Permalink
Post by Thomas Klausner
Post by Nick Bowler
Post by Thomas Klausner
AC_CACHE_CHECK([parameter type for backtrace()],
[am_cv_proto_backtrace_type],
The am_cv_ prefix is used by Automake so I suggest choosing a
different one.
What do you suggest using as prefixes?
Something relevant to your project. For example, gnulib uses gl_,
coreutils uses cu_, libtool uses lt_, m4 uses M4_. It doesn't have to
be limited to 2 alphabetics; but it should be your own prefix rather
than stomping on ac_ (autoconf) or am_ (automake), so that your package
isn't hurt if the autotools later make use of that variable name in a
different way.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Loading...