473,382 Members | 1,689 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

What types are legal as (...) arguments?

Hello, all!

i'm working on a program where i'm making heavy use of (...) arguments
and i have a question about them. It's all working fine and well, but
i'm getting a warning from one compiler which makes the think that
perhaps my usage isn't portable, and i want to find out what C says
about my use case (rather than what my compilers say).

Consider:

struct my_struct {
int i;
struct my_struct * left;
struct some_struct bar;
};

Now, assuming i have a routine:

void do_mything( struct context *, ... );

i'm calling that like:

static const my_struct end; /* special argument to signal end of list
*/
my_struct foo;
my_struct bar;
.... initialize structs ...

do_mything( myContext, foo, bar, end );

My question is simple: is it legal (strictly speaking) to pass objects
other than built-in types here? gcc and SunStudio compilers don't
complain about it and the code words as expected, but tcc says
"warning: assignment of read-only location" (but it still works as
expected), so my suspicion is that gcc and SunCC are being too lenient
on me and that tcc is trying to tip me off to a violation of the
standard.

If it makes a difference, i'm trying to code for pre-C99, but i also
don't mind if i have to rely on C99 features.

To cut off the anticipated counter-question in advance: "why not pass
pointers to my_struct instead?" The answer is:

a) i do. i have two variants of my routines: one takes a list of
pointers and one takes a list of value types.
b) both approaches have slightly different implications in my library
and both are useful in different contexts.

:-?
Oct 24 '08 #1
12 2236
Stephan Beal <sg****@googlemail.comwrites:
[...]
Consider:

struct my_struct {
int i;
struct my_struct * left;
struct some_struct bar;
};

Now, assuming i have a routine:

void do_mything( struct context *, ... );

i'm calling that like:

static const my_struct end; /* special argument to signal end of list
*/
my_struct foo;
my_struct bar;
... initialize structs ...

do_mything( myContext, foo, bar, end );
[...]

It would be helpful if you posted more complete code. You haven't
shown us the declaration of my Context. Is it an object of type
struct context*?

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 24 '08 #2
On Oct 24, 6:41 pm, Keith Thompson <ks...@mib.orgwrote:
It would be helpful if you posted more complete code. You haven't
shown us the declaration of my Context. Is it an object of type
struct context*?
That's irrelevant for this purpose - i'm interested in the (...) args.
In this example the context is only there so i have an argument to
pass to va_start(). The exact types used are not significant for this
example, either, other than to demonstrate that i'm passing structs of
arbitrary size *by value* via (...)/va_list, and i'm curious as to
whether doing so is strictly C (or C99) compliant or whether i'm
unintentionally relying on a compiler-specific extension.

Oct 24 '08 #3
Stephan Beal wrote:
Hello, all!

i'm working on a program where i'm making heavy use of (...) arguments
and i have a question about them. It's all working fine and well, but
i'm getting a warning from one compiler which makes the think that
perhaps my usage isn't portable, and i want to find out what C says
about my use case (rather than what my compilers say).

Consider:

struct my_struct {
int i;
struct my_struct * left;
struct some_struct bar;
};

Now, assuming i have a routine:

void do_mything( struct context *, ... );

i'm calling that like:

static const my_struct end; /* special argument to signal end of list
*/
my_struct foo;
my_struct bar;
In each of the above cases, you were supposed to have "struct
my_struct", not just plain "my_struct". Did you make a typedef you
haven't shown us, or are you're compiling this as C++ code, rather
than as C code? If this is C++, your question actually belongs on
comp.lang.c++, not here.
... initialize structs ...

do_mything( myContext, foo, bar, end );

My question is simple: is it legal (strictly speaking) to pass objects
other than built-in types here? gcc and SunStudio compilers don't
complain about it and the code words as expected, but tcc says
"warning: assignment of read-only location" (but it still works as
expected), so my suspicion is that gcc and SunCC are being too lenient
on me and that tcc is trying to tip me off to a violation of the
standard.
The code you've written does not seem to contain any "assignment of
read-only location". The only thing you've shown us that could be
stored in read-only memory is 'end', and your code reads that value,
it doesn't write it.

Therefore, I suspect that the problem may be due to some code that you
haven't shown us. Please provide a complete, compilable piece of code,
as simple as possible. Please confirm that tcc produces the same error
message on the simplified code as it does on your actual code.

The following is the simplest piece of code I could come up with,
consistent with what you've already written. Does tcc issue any
warning messages when compiling it?

#include <stdarg.h>
struct context {
int i;
};

struct some_struct {
int i;
};

struct my_struct {
int i;
struct my_struct * left;
struct some_struct bar;
};

void do_mything( struct context *, ... );

int main(void)
{
static const struct my_struct end;
/* special argument to signal end of list */

struct my_struct foo = {0};
struct my_struct bar = {0};
struct context actual = {0};
struct context *myContext = &actual;

do_mything( myContext, foo, bar, end );
return 0;
}

void do_mything( struct context *myContext, ... ){
va_list ap;
va_start(ap, myContext);
struct my_struct foo = va_arg(ap, struct my_struct);
struct my_struct bar = va_arg(ap, struct my_struct);
struct my_struct end = va_arg(ap, struct my_struct);
va_end(ap);
}
Oct 24 '08 #4
On Oct 24, 8:10 pm, jameskuy...@verizon.net wrote:
The following is the simplest piece of code I could come up with,
consistent with what you've already written. Does tcc issue any
warning messages when compiling it?
Yes, exactly. Let's see what happens:

stephan@jareth:~/cvs/fossil/pegc/src$ gcc -c foo.c
stephan@jareth:~/cvs/fossil/pegc/src$ tcc -c foo.c
foo.c:31: warning: assignment of read-only location
stephan@jareth:~/cvs/fossil/pegc/src$ sed -n 29,33p < foo.c
struct context *myContext = &actual;

--here-- do_mything( myContext, foo, bar, end );
return 0;

(Thanks for that example, by the way. i was about to go factor an
example out of my existing code.)

So it seems that this is a bogus warning, and not a violation of the C
standard?
Oct 24 '08 #5
Stephan Beal <sg****@googlemail.comwrites:
On Oct 24, 6:41 pm, Keith Thompson <ks...@mib.orgwrote:
>It would be helpful if you posted more complete code. You haven't
shown us the declaration of my Context. Is it an object of type
struct context*?

That's irrelevant for this purpose - i'm interested in the (...) args.
In this example the context is only there so i have an argument to
pass to va_start(). The exact types used are not significant for this
example, either, other than to demonstrate that i'm passing structs of
arbitrary size *by value* via (...)/va_list, and i'm curious as to
whether doing so is strictly C (or C99) compliant or whether i'm
unintentionally relying on a compiler-specific extension.
Actual code is almost always relevant. The code you posted (a) is
incomplete, and (b) seems unlikely to trigger the warning message you
say you're seeing. It's possible that you've assumed that the warning
message is caused by your used of struct parameters in a variadic
function.

If you posted a complete self-contained program that produces the
warning, we'd have a much better chance of telling you why you're
getting the warning.

As far as the language (either C90 or C99) is concerned, there should
be no problem passing either pointers or structures as arguments to a
variadic function, as long as you invoke va_arg and friends properly
within the function. The only problems you can expect are from using
types that are promoted (which pointers and structures aren't). But
it's entirely possible that a compiler could have a bug in this area;
passing structures to variadic functions is a fairly unusual thing to
do.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 24 '08 #6
On Oct 24, 8:44 pm, Keith Thompson <ks...@mib.orgwrote:
Actual code is almost always relevant. The code you posted (a) is
You're right, and i appologize for not posting an example. My question
was not about the code, really, but more about about what limitations
the C standard may or may not prescribe for varargs.
As far as the language (either C90 or C99) is concerned, there should
be no problem passing either pointers or structures as arguments to a
variadic function, as long as you invoke va_arg and friends properly
within the function.
Thank you for that. That's EXACTLY the answer i was looking for.
The only problems you can expect are from using
types that are promoted (which pointers and structures aren't). But
it's entirely possible that a compiler could have a bug in this area;
passing structures to variadic functions is a fairly unusual thing to
do.
i hope to keep my va_list usage to a minimum (i find it too error-
prone
for the general case), so i hope i won't run into any tricky cases.

My many thanks for your time :). i will rest easier tonight with the
knowledge that i don't have to go remove the (...) bits from my API.
Oct 24 '08 #7
Stephan Beal <sg****@googlemail.comwrites:
On Oct 24, 8:44 pm, Keith Thompson <ks...@mib.orgwrote:
>Actual code is almost always relevant. The code you posted (a) is

You're right, and i appologize for not posting an example. My question
was not about the code, really, but more about about what limitations
the C standard may or may not prescribe for varargs.
>As far as the language (either C90 or C99) is concerned, there should
be no problem passing either pointers or structures as arguments to a
variadic function, as long as you invoke va_arg and friends properly
within the function.

Thank you for that. That's EXACTLY the answer i was looking for.
>The only problems you can expect are from using
types that are promoted (which pointers and structures aren't). But
it's entirely possible that a compiler could have a bug in this area;
passing structures to variadic functions is a fairly unusual thing to
do.

i hope to keep my va_list usage to a minimum (i find it too error-
prone
for the general case), so i hope i won't run into any tricky cases.

My many thanks for your time :). i will rest easier tonight with the
knowledge that i don't have to go remove the (...) bits from my API.
I should warn you, though, that I recently made a serious error here
discussing variadic functions. (I assumed that the parameter
preceding the ",..." could be of any type; in fact, if it's of a type
that's affected by argument promotions, i.e., either float or an
integer type narrower than int, then the behavior is undefined.) I
*think* I've got it right this time, but I'm not certain. If nobody
posts a correction, I'll be more confident.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 24 '08 #8
Stephan Beal wrote:
On Oct 24, 8:10 pm, jameskuy...@verizon.net wrote:
The following is the simplest piece of code I could come up with,
consistent with what you've already written. Does tcc issue any
warning messages when compiling it?

Yes, exactly. Let's see what happens:

stephan@jareth:~/cvs/fossil/pegc/src$ gcc -c foo.c
stephan@jareth:~/cvs/fossil/pegc/src$ tcc -c foo.c
foo.c:31: warning: assignment of read-only location
stephan@jareth:~/cvs/fossil/pegc/src$ sed -n 29,33p < foo.c
struct context *myContext = &actual;

--here-- do_mything( myContext, foo, bar, end );
return 0;

(Thanks for that example, by the way. i was about to go factor an
example out of my existing code.)

So it seems that this is a bogus warning, and not a violation of the C
standard?
I believe so. I can't see anything wrong with it, nor can I see any
meaningful connection between the warning message and the code that it
is supposed to be referring to.
Oct 24 '08 #9
On Oct 24, 1:28*pm, Keith Thompson <ks...@mib.orgwrote:

snip
I should warn you, though, that I recently made a serious error here
discussing variadic functions. *(I assumed that the parameter
preceding the ",..." could be of any type; in fact, if it's of a type
that's affected by argument promotions, i.e., either float or an
integer type narrower than int, then the behavior is undefined.) *I
*think* I've got it right this time, but I'm not certain. *If nobody
posts a correction, I'll be more confident.
This doesn't look right for function calls with a prototype in scope.
I have tried to see where this would be derived from 6.5.2.2 and there
doesn't appear to be a restriction on the parameters preceding the
ellipses. Nor are these parameters promoted.
Oct 25 '08 #10
Barry Schwarz <sc*******@yahoo.comwrites:
On Oct 24, 1:28*pm, Keith Thompson <ks...@mib.orgwrote:

snip
>I should warn you, though, that I recently made a serious error here
discussing variadic functions. *(I assumed that the parameter
preceding the ",..." could be of any type; in fact, if it's of a type
that's affected by argument promotions, i.e., either float or an
integer type narrower than int, then the behavior is undefined.) *I
*think* I've got it right this time, but I'm not certain. *If nobody
posts a correction, I'll be more confident.

This doesn't look right for function calls with a prototype in scope.
I have tried to see where this would be derived from 6.5.2.2 and there
doesn't appear to be a restriction on the parameters preceding the
ellipses. Nor are these parameters promoted.
The problem comes from:

7.15.1.4 The va_start macro

in which paragraph 4 reads:

4 The parameter parmN is the identifier of the rightmost parameter
in the variable parameter list in the function definition (the
one just before the , ...). If the parameter parmN is declared
with the register storage class, with a function or array type,
or with a type that is not compatible with the type that results
after application of the default argument promotions, the
behavior is undefined.

It is hardly surprising that Keith missed this[1] since it seems to be
a pointless extra condition. Section 6.5.2.2 says that in a call to a
vararg function with a prototype in scope, the initial parameters are
converted (as if by assignment) to the declared types, and (in another
paragraph) that a call to a vararg function without a prototype in
scope is UB. Thus the whole call is either UB or there is prototype
in scope that precludes any need to apply the default argument
promotions.

I can only assume that the intent is to permit implementations to
apply the default argument promotions on all arguments to a vararg
function call. Maybe that is the only way to arrange such calls and
the stdarg.h macros on some obscure architecture?

[1] I missed it too but that is way less surprising and, consequently,
far less noteworthy.

--
Ben.
Oct 25 '08 #11
jameskuy...@verizon.net wrote:
Stephan Beal wrote:
stephan@jareth:~/cvs/fossil/pegc/src$ tcc -c foo.c
foo.c:31: warning: assignment of read-only location

So it seems that this is a bogus warning, and not a violation of the C
standard?

I believe so. I can't see anything wrong with it, nor can I see any
meaningful connection between the warning message and the code that it
is supposed to be referring to.
I would be suspicious as to whether the compiler
is actually generating correct code, given that it
seems to not be handling the source code properly.
Oct 29 '08 #12
Old Wolf <ol*****@inspire.net.nzwrites:
jameskuy...@verizon.net wrote:
>Stephan Beal wrote:
stephan@jareth:~/cvs/fossil/pegc/src$ tcc -c foo.c
foo.c:31: warning: assignment of read-only location

So it seems that this is a bogus warning, and not a violation of the C
standard?

I believe so. I can't see anything wrong with it, nor can I see any
meaningful connection between the warning message and the code that it
is supposed to be referring to.

I would be suspicious as to whether the compiler
is actually generating correct code, given that it
seems to not be handling the source code properly.
It is. I checked.
Oct 29 '08 #13

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

Similar topics

1
by: Ajax Chelsea | last post by:
1,int (*f)(int a = 1);//is it legal? 2,int (*f)(int a = 1); int g(int a = 2){return 0;} f = &g;//is it legal?
140
by: Oliver Brausch | last post by:
Hello, have you ever heard about this MS-visual c compiler bug? look at the small prog: static int x=0; int bit32() { return ++x; }
51
by: jacob navia | last post by:
I would like to add at the beginning of the C tutorial I am writing a short blurb about what "types" are. I came up with the following text. Please can you comment? Did I miss something? Is...
24
by: Romeo Colacitti | last post by:
Hi, Does anyone here have a strong understanding for the meanings of the terms "lvalue" and "rvalue" as it pertains to C, objects, and different contexts? If so please share. I've been...
3
by: baumann | last post by:
hi all, i could not understand the "unnecessary" pointer comparison. /* 207 * min()/max() macros that also do 208 * strict type-checking.. See the 209 * "unnecessary" pointer comparison....
669
by: Xah Lee | last post by:
in March, i posted a essay “What is Expressiveness in a Computer Language”, archived at: http://xahlee.org/perl-python/what_is_expresiveness.html I was informed then that there is a academic...
132
by: Frederick Gotham | last post by:
If we look at a programming language such as C++: When an updated Standard comes out, everyone adopts it and abandons the previous one. It seems though that things aren't so clear-cut in the C...
20
by: Chris | last post by:
I'm not sure if this has been done before, but I couldn't easily find any prior work on Google, so here I present a simple decorator for documenting and verifying the type of function arguments....
6
by: Charles Sullivan | last post by:
I define and initialize an array of structures like the following, (where the <verbiage within angle bracketsis just meant to be explanatory): int func1(<argument prototypes>); int...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

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.