This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Problem with type safety and the "sentinel" attribute
- From: Stefan Westerfeld <stefan at space dot twc dot de>
- To: gcc at gcc dot gnu dot org
- Cc: timj at gtk dot org
- Date: Fri, 9 Jun 2006 17:26:46 +0200
- Subject: Problem with type safety and the "sentinel" attribute
Hi!
I recently tried to add sentinel attributes to the beast code, and found
that the way gcc treats sentinels right now, we need to make a trade off
between type safety against the sentinel NULL termination check. The
GNOME bugzilla link is here:
http://bugzilla.gnome.org/show_bug.cgi?id=344388
But I made a little self contained example, so you can see the problem
right here:
#include <stdio.h>
#include <stdarg.h>
static void print_string_array (const char *array_name,
const char *string, ...) __attribute__ ((__sentinel__));
static void
print_string_array (const char *array_name,
const char *string, ...)
{
va_list ap;
printf ("strings in %s = [", array_name);
for (va_start (ap, string); string; string = va_arg (ap, const char *))
printf (" '%s'", string);
va_end(ap);
printf (" ];\n");
}
int
main()
{
print_string_array ("foo_array", "string1", "string2", "string3", NULL);
print_string_array ("empty_array", NULL); /* gcc warns, but shouldn't */
return 0;
}
The program compiles and runs like this:
stefan@lotrien:~/tmp$ gcc -o fmt-sentinel fmt-sentinel.c -Wall
fmt-sentinel.c: In function 'main':
fmt-sentinel.c:23: warning: not enough variable arguments to fit a sentinel
stefan@lotrien:~/tmp$ fmt-sentinel
strings in foo_array = [ 'string1' 'string2' 'string3' ];
strings in empty_array = [ ];
stefan@lotrien:~/tmp$
So you see, although we think the second call of print_string_array is
correct (and makes sense in this toy program), gcc doesn't, because the
NULL sentinel doesn't occur within the varargs section of the parameter
list.
The only way out for keeping the sentinel attribute and avoiding the
warning is using
static void print_string_array (const char *array_name, ...) __attribute__ ((__sentinel__));
as function prototype, so that the first string also becomes one of the
varargs arguments. But this makes the code less typesafe, because then
the compiler can no longer check that the first "string" argument the
caller passes is really a "const char *".
I was wondering if the sentinel attribute could be modified or extended
in a way that we don't need to trade type safety against NULL
termination check, but can have both?
By the way, there is already an existing gcc bug, which is about the
same thing (NULL passed within named args), but wants to have it the way
it works now:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21911
so if it gets changed, then gcc might need to support both
- NULL termination within the last named parameter allowed
- NULL termination only allowed within varargs parameters (like it is
now)
Cu... Stefan
--
Stefan Westerfeld, Hamburg/Germany, http://space.twc.de/~stefan