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.
:-? 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"
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.
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);
}
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?
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"
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.
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"
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.
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.
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.
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.
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
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?
|
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;
}
|
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...
|
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...
|
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....
|
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...
|
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...
|
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....
|
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...
|
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...
|
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...
|
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,...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
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...
|
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...
|
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
|
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...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
| |