473,671 Members | 2,121 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2254
Stephan Beal <sg****@googlem ail.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_Keit h) 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.orgw rote:
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...@ver izon.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****@googlem ail.comwrites:
On Oct 24, 6:41 pm, Keith Thompson <ks...@mib.orgw rote:
>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_Keit h) 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.orgw rote:
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****@googlem ail.comwrites:
On Oct 24, 8:44 pm, Keith Thompson <ks...@mib.orgw rote:
>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_Keit h) 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...@ver izon.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.orgw rote:

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

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

Similar topics

1
1578
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
7819
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
4511
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 there something wrong in there? -------------------------------------------------------------------- Types A type is a definition for a sequence of storage bits. It gives the meaning of the data stored in memory. If we say that the object a is an
24
2951
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 reading several old posts/threads on the subject, and they never end with a conclusion (people keep correcting each other and disagreeing).
3
2479
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. 210 */ 211 #define min(x,y) ({ \
669
25866
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 paper written on this subject. On the Expressive Power of Programming Languages, by Matthias Felleisen, 1990. http://www.ccs.neu.edu/home/cobbe/pl-seminar-jr/notes/2003-sep-26/expressive-slides.pdf
132
4581
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 community. It would seem that C99 is the most up-to-date Standard, but far more people seem to be working off the C89 Standard. Could someone please explain to me why this is so? --
20
1951
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. Feedback/suggestions/criticism is welcome. ''' 2006.12.21 Created. ''' import unittest
6
2200
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 func2(<argument prototypes>); struct mystruct { <other stuff>; int (*myfunc)();
0
8476
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main usage, and What is the difference between ONU and Router. Lets take a closer look ! Part I. Meaning of...
0
8914
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8598
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8670
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7433
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development projectplanning, coding, testing, and deploymentwithout human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6223
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 presenter, Adolph Dupr who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5695
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4224
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4406
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

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.