473,499 Members | 1,669 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

va_list: how to produce warnings at compile time if calledincorrectly?

Hi,

I would like to write a variadic function f(const int MY_TYPE_X, ...) were MY_TYPE_X is not the amount of arguments but an index representing both: the amount of args and their type.

So, for each MY_TYPE_X, it should be allowed to call f only as if it were either f1, f2 or f3:

void f1(MY_TYPE_0, int){ /* ... */ }
void f2(MY_TYPE_1, int, void*, char*){ /* ... */ }
void f3(MY_TYPE_2, long, long){ /* ... */}

My question: Can I make the compiler produce warnings like with printf called incorrectly? E.g., this should produce a warning:

f(MY_TYPE_0, "a string", 99);

Felix
May 16 '06 #1
13 1654


Felix Kater wrote On 05/16/06 09:30,:
Hi,

I would like to write a variadic function f(const int MY_TYPE_X, ...) were MY_TYPE_X is not the amount of arguments but an index representing both: the amount of args and their type.

So, for each MY_TYPE_X, it should be allowed to call f only as if it were either f1, f2 or f3:

void f1(MY_TYPE_0, int){ /* ... */ }
void f2(MY_TYPE_1, int, void*, char*){ /* ... */ }
void f3(MY_TYPE_2, long, long){ /* ... */}

My question: Can I make the compiler produce warnings like with printf called incorrectly? E.g., this should produce a warning:

f(MY_TYPE_0, "a string", 99);


The language itself has no way to restrict the "..."
arguments. You cannot even say "They must all be ints"
or "They must come in int/char* pairs." The compiler you
use may have extra-linquistic features to allow this, but
the C language can't do it unaided.

My question, though: If you've got f1(),f2(),f3()
with known, fixed-length argument "signatures," why do
you want to somehow collapse them all into a single
variadic function f()? What does it gain you (you've
already discovered some of what it loses)?

--
Er*********@sun.com

May 16 '06 #2
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:
The language itself has no way to restrict the "..."
arguments.


I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.
So, shouldn't it be possible somehow?

Felix
May 16 '06 #3
Felix Kater wrote:
Hi,

I would like to write a variadic function f(const int MY_TYPE_X, ...) were MY_TYPE_X is not the amount of arguments but an index representing both: the amount of args and their type.

So, for each MY_TYPE_X, it should be allowed to call f only as if it were either f1, f2 or f3:

void f1(MY_TYPE_0, int){ /* ... */ }
void f2(MY_TYPE_1, int, void*, char*){ /* ... */ }
void f3(MY_TYPE_2, long, long){ /* ... */}

My question: Can I make the compiler produce warnings like with printf called incorrectly? E.g., this should produce a warning:

f(MY_TYPE_0, "a string", 99);


I would say that this was implementation specific only I doubt that you
can do it with any implementation. Just on the off chance I am wrong and
you can, ask on a group dedicated to your implementation.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
May 16 '06 #4
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:
My question, though: If you've got f1(),f2(),f3()
with known, fixed-length argument "signatures," why do
you want to somehow collapse them all into a single
variadic function f()? What does it gain you (you've
already discovered some of what it loses)?


My idea is to create a general function f which first does some general
things (according on groups of MY_TYPE_X passed as the first arg) and
then calls the appropriate callback to the other arguments are passed.
So, in other words I'd like to help myself and other developers in my
project in the way that those "general things" are done in any case
so we can concentrate on the callbacks. One simple example of these
general things is to first check in each new public function if the
module was initialized.

Felix
May 16 '06 #5

Felix Kater wrote:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:
The language itself has no way to restrict the "..."
arguments.


I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.
So, shouldn't it be possible somehow?


The warning is courtesy of GCC. It is not required by the standard.

May 16 '06 #6


Felix Kater wrote On 05/16/06 11:11,:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:

The language itself has no way to restrict the "..."
arguments.

I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.
So, shouldn't it be possible somehow?


That's one of those "extra-linguistic features" I
mentioned. gcc has a gcc-specific way of checking for
disagreement between printf-like and scanf-like format
strings and the arguments provided to match them. It
may be possible to get gcc to make other kinds of checks
as well; consult the gcc documentation.

But all these things are specific to gcc; the C
language itself has no way of expressing any restrictions
on the "..." arguments. Since the restrictions cannot
even be expressed, they cannot be enforced -- without,
as I said, going outside the language and dealing directly
with the compiler, whether it's gcc or something else.

--
Er*********@sun.com

May 16 '06 #7
On 2006-05-16, Felix Kater <fk****@googlemail.com> wrote:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:
The language itself has no way to restrict the "..."
arguments.


I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.
So, shouldn't it be possible somehow?

Using gcc-specific extensions, it is certainly possible. I get
the illusion that printf is built right into the compiler from
some of the errors it gives me.

May 16 '06 #8


Felix Kater wrote On 05/16/06 11:22,:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:

My question, though: If you've got f1(),f2(),f3()
with known, fixed-length argument "signatures," why do
you want to somehow collapse them all into a single
variadic function f()? What does it gain you (you've
already discovered some of what it loses)?

My idea is to create a general function f which first does some general
things (according on groups of MY_TYPE_X passed as the first arg) and
then calls the appropriate callback to the other arguments are passed.
So, in other words I'd like to help myself and other developers in my
project in the way that those "general things" are done in any case
so we can concentrate on the callbacks. One simple example of these
general things is to first check in each new public function if the
module was initialized.


It seems to me it would be less burdensome to put the
initialization checks into f1(),f2(),f3() than to require
the user to write f(please_call_f1_for_me, f1_arguments).

--
Er*********@sun.com

May 16 '06 #9
Eric Sosman <Er*********@sun.com> writes:
Felix Kater wrote On 05/16/06 11:11,:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:

The language itself has no way to restrict the "..."
arguments.

I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.
So, shouldn't it be possible somehow?


That's one of those "extra-linguistic features" I
mentioned. gcc has a gcc-specific way of checking for
disagreement between printf-like and scanf-like format
strings and the arguments provided to match them. It
may be possible to get gcc to make other kinds of checks
as well; consult the gcc documentation.


I don't think it is gcc-specific, in that any compiler could in
principle do this for printf (and sprintf, scanf etc) because the
format string meaning is defined by the C standard. Same thing with
replacing printf() calls with puts(), where these would be equivalent
(which gcc also does). gcc is allowed to assume that the standard
library functions behave according to the standard, and it does this
in several areas.

But for user-written functions it has no way of knowing, within
standard C, what the format string is supposed to mean.
But all these things are specific to gcc; the C
language itself has no way of expressing any restrictions
on the "..." arguments. Since the restrictions cannot
even be expressed, they cannot be enforced -- without,
as I said, going outside the language and dealing directly
with the compiler, whether it's gcc or something else.


--

John Devereux
May 16 '06 #10
Felix Kater wrote:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:
The language itself has no way to restrict the "..."
arguments.
I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.


gcc has a parser for the printf built in to it.
So, shouldn't it be possible somehow?


How on earth is it going to be possible in the general case? I could
write my own printf like function that uses different format specifiers,
being indicated by a different character, and I would have to be able to
describe that to the compiler. I could also have a function where every
other parameter tells the function what type the next parameter is, but
the encoding of the type information changes dependant on the type of
the last but one parameter pair.

Can you really come up with a generic method to describe all possible
ways that the parameter types could be determined? Given that there are
people like me who can be exceedingly devious?

The final word on this is that the C standard, the document that
actually defined the C programming language, does not specify any
mechanism to do what you want, therefore even if it was very simple to
do (as in some cases with printf) then there would *still* be no way to
do it as far as C is concerned.

As I said in another post, if you want to know if there is any way to
get your compiler to do any checking for you as in a group dedicated to it.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
May 16 '06 #11


John Devereux wrote On 05/16/06 11:53,:
Eric Sosman <Er*********@sun.com> writes:

Felix Kater wrote On 05/16/06 11:11,:
On Tue, 16 May 2006 10:53:08 -0400
Eric Sosman <Er*********@sun.com> wrote:

The language itself has no way to restrict the "..."
arguments.
I wonder how printf does that? If I do

long my_long=0;
printf("%d",my_long);

I get a warning from gcc that an int was expected.
So, shouldn't it be possible somehow?
That's one of those "extra-linguistic features" I
mentioned. gcc has a gcc-specific way of checking for
disagreement between printf-like and scanf-like format
strings and the arguments provided to match them. It
may be possible to get gcc to make other kinds of checks
as well; consult the gcc documentation.

I don't think it is gcc-specific, in that any compiler could in
principle do this for printf (and sprintf, scanf etc) because the
format string meaning is defined by the C standard. Same thing with
replacing printf() calls with puts(), where these would be equivalent
(which gcc also does). gcc is allowed to assume that the standard
library functions behave according to the standard, and it does this
in several areas.


Thanks for the correction. I ought to have said that
the mechanism gcc actually uses for these checks is a gcc-
specific mechanism, not that the checking itself has to be
gcc-specific.
But for user-written functions it has no way of knowing, within
standard C, what the format string is supposed to mean.


As it happens, gcc's mechanism can be used to tag user-
written functions, too. If you want to write a logging
function that takes a printf-like format string and matching
arguments, you can get gcc to check it for you. I haven't
studied the gcc annotations enough to tell whether they're
easily extensible to the kinds of checks the O.P. wants, though.

--
Er*********@sun.com

May 16 '06 #12
On Tue, 16 May 2006 11:41:48 -0400
Eric Sosman <Er*********@sun.com> wrote:
It seems to me it would be less burdensome to put the
initialization checks into f1(),f2(),f3() than to require
the user to write f(please_call_f1_for_me, f1_arguments).


Hm. Initialization checks were just an example. I have to keep an eye
on much more like module dependencies, its actual runlevels an so on.

So, let me get it this way then: It's not only about keeping the
interface (more or less) easy to use for the client programmer. But for
larger projects it's not less important to keep the code simple for
changes an extensions to the developers of the project. In our case it
got hard to change anything since the developers have to think of too
many things before being able to change anything. A good redesign is my
motivation--letting the user do some more overhead is ok if this makes
it possible for the developers to keep on coding.

Of course, I don't want to make things more complicated than necessary.

I was thinking of doing things like this

general_f(create_new_struct_of_same_type_f1( int i, long l))
general_f(create_new_struct_of_same_type_f2( void*, char*))

But to have this convenient to the client, general_f should detroy
the structs internally--but what with return values, then? ...I am
still not convinced of it all.

Felix
May 16 '06 #13
To use printf cech format ( gcc only ) you must use
__attribute__ format
you can find more details here:
http://www.unixwiz.net/techtips/gnu-...es.html#format
or in gcc manual.

May 17 '06 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
16750
by: Douwe | last post by:
I try to build my own version of printf which just passes all arguments to the original printf. As long as I keep it with the single argument version everything is fine. But their is also a version...
12
4864
by: Charlie Zender | last post by:
Hi, I am unable to compile a large body of code with extremely pedantic compile time checks activate, so that warnings cause errors. With GCC 3.3.1, I do this with gcc -std=c99 -pedantic...
2
3314
by: Joerg Schoen | last post by:
Hi folks! I have a function that gets a 'va_list'. I am passing the 'va_list' two times to a function like 'vprintf' to print it out. I thought that this was portable until I came across a...
5
11481
by: P. Hari Krishna | last post by:
Hi, I have a situation where I do not know the number of arguments I pass to a function at compile time. So is there any way, that we can programmatically create a "va_list" and then pass it to...
5
1774
by: rawCoder | last post by:
Hi All, In Visual Basic .NET , your function definition might requirre you to return a value but (accidently/intentionally) you dont put any 'return value' in the function. In this case VB...
7
2844
by: Flash Gordon | last post by:
Reading the standard, va_list is an object type (, so I believe the following should be possible: #include <stdarg.h> void foo(va_list *arg) { /* do some stuff which conditionally might read...
5
4617
by: =?ISO-8859-1?Q?Tom=E1s_=D3_h=C9ilidhe?= | last post by:
On Jun 3, 3:23 am, Jesse Ziser <d...@spam.diewrote: The relevant paragraph from the Standard is: ---- Begin Quote ---- The type declared is va_list which is an object type suitable for...
6
4043
by: Laurent Deniau | last post by:
When I compile the code below with gcc -std=c99 -W -Wall -pedantic -O3 -Winline, it reports the following: variadic.c: In function ‘fv’: variadic.c:12: warning: function ‘fv’ can never be...
1
5500
by: Chuck Chopp | last post by:
I have some code that is being built on the following: Windows Server 2003, both 32-bit & 64-bit editions Windows Vista, both 32-bit & 64-bit editions Windows Server 2008, both 32-bit & 64-bit...
0
7134
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7014
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
1
6905
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
7395
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
1
4921
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3108
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
3103
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
667
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
311
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.