As the committee gathered to discuss how the new C standard will look like I did some thinking of my own. I thought about features that I would love to see in C. I even collected thoughts of my twisted mind and condensed them into a text file.
What is outrageous is that since I believe information and ideas want to be free and shared I have decided to post my concepts on the net instead of imprisoning them in my wicked brain.
Maybe someone will find it useful somehow. Maybe even some committee member will read those and bring them out on next meeting. In any case, feel free to ignore this thread. :)
1. The default value of a function's argument has proved to be useful in C++ programs as well as in other languages which has such a notion. It allows for more condensed function call in the usual cases still allowing for a configuration when required.
2. Syntax and semantics of such feature should be the same as in C++.
struct void *get(struct node *first, int key, const char *def = NULL) { for (; first; first = first->next) { if (first->key == key) return first->value; return def; } #v-
4. In the current standard, such syntax it is invalid thus it will not affect existing code. Moreover, many C implementations are also capable of accepting C++ code thus implementing this feature would be an easy task in many such cases.
II *Named Arguments*
1. It has been observed that calls to functions with many arguments are somehow unreadable since it is hard to keep track of which argument means what.
2. To mitigate this problem named arguments could be added to the C language with a syntax similar to one used in structures and union initialisation.
4. The name of the argument would become part of a function's prototype thus the following would be illegal:
#v+ void f1(int .bar); void f1(int .baz); /* different name */ void f2(int bar); void f2(int .bar); /* unnamed vs. unnamed */ #v-
5. If different names (or lack of names) was used in different translation unit behaviour would be still well defined as long as order and types of arguments match.
6. Similarly, when taking function's address or casting between pointers to functions the names of arguments would be ignored, hence the following would be still well defined and perfectly legal:
format("%s is ready", dish_name, .level = LVL_INFO, .colour = WHITE); format(.level = LVL_ERROR, .colour = READ, "%s is burnt", cake_name); format("we are out of %s", .level = LVL_WARN, .colour = WHITE, resource_name); #v-
9. Proposed syntax is an invalid syntax in the current standard so this change would not impact existing code. At the same time, implementations use such syntax in initialisation list thus it would be simplified to use the same syntax in named arguments.
10. Named arguments would be especially powerful with conjunction with default value. In particular, `format()` could be defined as:
#v+ format("%s is ready", dish_name); format(.level = LVL_ERROR, .colour = READ, "%s is burnt", cake_name); format("we are out of %s", .level = LVL_WARN, resource_name); #v-
III *Inlined Structures and Unions*
1. The new standard draft allow declaration of anonymous structures and anonymous unions in structures and unions:
#v+ struct { union { int i; struct { short s; char c; }; }; } a;
/* All valid: */ a.i; a.s; a.c; #v-
2. This technique is used already by some C implementations and has proved useful however is limited to a simple case. A syntax where by using `inline` keyword one could achieve similar effect for named structures (especially defined elsewhere) or fields that otherwise have name could be handy.
4. The `inline` keyword would mean that all the members of the structure or union are accessible from namespace the declaration is in.
5. An optional list of identifier would make only listed identifiers be accessible from the namespace. An empty list would mean no identifiers would be inlined but this would be useful with casting -- read further.
6. An optional identifier would allow accessing the structure as a whole as well as each individual member via the name.
7. Example:
#v+ struct s1 { int i1, j1; }; struct s2 { int i2, j2; }; struct s3 { int i3, j3; };
struct { struct s1 inline; struct s2 s inline; struct s3 a inline(i3); struct s3 b inline(j3); } s;
/* To reach each of the fields: */ s.i1; s.j1; s.i2; /* same as */ s.s.i2; s.j2; /* same as */ s.s.j2; s.i3; /* same as */ s.a.s3; s.j3; /* same as */ s.b.j3; s.a.j3; s.b.i3; #v-
8. This allows to nicely build structures that share some common data. For instance:
union header header; if (header.type == FOO_HEADER_TYPE) { handle_foo(&header.foo); } else if (header.type == BAR_HEADER_TYPE) { handle_foo(&header.bar); } else { error(); } #v-
9. This would not be limited to defining structure's or union's members but could be used in other scopes. For instance:
#v+ void do_stuff(int use_double) { union { float f; double d; } inline; if (use_double) /* ... do stuff using "d" */ else /* ... do stuff using "f" */ } #v-
10. Proposed syntax is not valid C99 syntax so it would not affect existing code.
IV *Casting to Inlined Members*
1. Inlined structures and unions would be especially powerful if implicit casting to an inlined member was allowed. This would allow for an object oriented programming without the need for explicit cast and/or run-time checking.
2. Example:
#v+ struct point { double x, y; }; struct circle { struct point inline; double r; };
4. For compatibility reasons, an explicit cast to a pointer to a type of one of inlined member would produce different results.
5. Explicit casting to inlined member would not need to be supported by the language as users could name an inlined member and use "&" operator to acquire it's address. For instance:
Just one quick comment; I might have more to say later.
> IV *Casting to Inlined Members*
> 1. Inlined structures and unions would be especially powerful if > implicit casting to an inlined member was allowed. This would > allow for an object oriented programming without the need for > explicit cast and/or run-time checking.
The phrase "implicit casting" makes no sense. A cast is an operator that specifies a conversion. You mean "implicit conversion".
-- 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"
> Michal Nazarewicz <min...@tlen.pl> writes: >> IV *Casting to Inlined Members*
>> 1. Inlined structures and unions would be especially powerful if >> implicit casting to an inlined member was allowed. This would >> allow for an object oriented programming without the need for >> explicit cast and/or run-time checking. Keith Thompson <ks...@mib.org> writes: > The phrase "implicit casting" makes no sense. A cast is an operator > that specifies a conversion. You mean "implicit conversion".
Thanks for pointing that out. Even though I like to think I know standard to some degree I wasn't aware of that.
-- Best regards, _ _ .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
>> Michal Nazarewicz <min...@tlen.pl> writes: >>> IV *Casting to Inlined Members*
>>> 1. Inlined structures and unions would be especially powerful if >>> implicit casting to an inlined member was allowed. This would >>> allow for an object oriented programming without the need for >>> explicit cast and/or run-time checking.
> Keith Thompson <ks...@mib.org> writes: >> The phrase "implicit casting" makes no sense. A cast is an operator >> that specifies a conversion. You mean "implicit conversion".
> Thanks for pointing that out. Even though I like to think I know > standard to some degree I wasn't aware of that.
ALl casts are conversions from one type to another. Forget thmpson, he just likes to posts this kind of messages so he looks important.
Some of your poposals are implemented in the lcc-win C compiler. Default function arguments for instance, generic functions.
I have been proposing those things here for years but this newsgroup has nothing to do with the committee.
There is a proposition in the committee now to eliminate some of the timid features of C99 so I think that there is no possibility of them approving anything innovating.
On 2010-04-19, jacob navia <ja...@nospam.org> wrote:
> I have been proposing those things here for years but this newsgroup > has nothing to do with the committee.
Well, a few people involved in the committee read and discuss in this newsgroup.
> There is a proposition in the committee now to eliminate some of the > timid features of C99 so I think that there is no possibility of > them approving anything innovating.
Such as, say, some threading support?
Your inability to accept data that don't confirm your pessimism is really disturbing.
jacob navia <ja...@nospam.org> writes: > Michal Nazarewicz a écrit : > >> Michal Nazarewicz <min...@tlen.pl> writes: > >>> IV *Casting to Inlined Members*
> >>> 1. Inlined structures and unions would be especially powerful if > >>> implicit casting to an inlined member was allowed. This would > >>> allow for an object oriented programming without the need for > >>> explicit cast and/or run-time checking. > > Keith Thompson <ks...@mib.org> writes: > >> The phrase "implicit casting" makes no sense. A cast is an operator > >> that specifies a conversion. You mean "implicit conversion". > > Thanks for pointing that out. Even though I like to think I know > > standard to some degree I wasn't aware of that.
> ALl casts are conversions from one type to another.
Yes, but not all conversions are casts. For example, in the following:
double x = 42;
there's an implicit conversion from int to double. There is no cast.
You've written a compiler, jacob; surely you know that.
> Forget thmpson, he just likes to posts this kind of messages so he > looks important.
Deliberately misspelling my name does not improve your credibility.
-- 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 2010-04-19, jacob navia <ja...@nospam.org> wrote: >> I have been proposing those things here for years but this newsgroup >> has nothing to do with the committee.
> Well, a few people involved in the committee read and discuss in this > newsgroup.
>> There is a proposition in the committee now to eliminate some of the >> timid features of C99 so I think that there is no possibility of >> them approving anything innovating.
> Such as, say, some threading support?
> Your inability to accept data that don't confirm your pessimism is > really disturbing.
> -s
The feature is not mandatory, it suffices to define a symbol and there, no thread support.
Seebs <usenet-nos...@seebs.net> writes: > On 2010-04-19, jacob navia <ja...@spamsink.net> wrote: > > The feature is not mandatory, it suffices to define a symbol and there, > > no thread support.
> So what? It's still unambiguously new feature work in the standard.
> Of course not everything becomes mandatory.
And in this particular case, the feature will be optional *only* if P.J. Plauger's proposal
is accepted. As of the N1425 draft, threading is just another language/library feature, with no indication that it's optional for hosted implementations.
Background: Plauger proposes making complex arithmetic, threads, and VLAs, and possibly atomics, optional in C201X. I have no idea how likely this proposal is to be accepted. I personally dislike the idea.
-- 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 2010-04-19, Keith Thompson <ks...@mib.org> wrote:
> Background: Plauger proposes making complex arithmetic, threads, > and VLAs, and possibly atomics, optional in C201X. I have no idea > how likely this proposal is to be accepted. I personally dislike > the idea.
I am torn. I recognize the issues in imposing these additional costs on implementations, but... VLAs have been awfully useful to me in cases where I have reasonable confidence that it's cheap to allocate something of about the right size and I won't run out of room.
Seebs wrote: > On 2010-04-19, Keith Thompson <ks...@mib.org> wrote: > > Background: Plauger proposes making complex arithmetic, threads, > > and VLAs, and possibly atomics, optional in C201X. I have no idea > > how likely this proposal is to be accepted. I personally dislike > > the idea.
> I am torn. I recognize the issues in imposing these additional > costs on implementations, but... VLAs have been awfully useful to me > in cases where I have reasonable confidence that it's cheap to > allocate something of about the right size and I won't run out of > room.
In general terms I like Bill's proposal.
We primarily create tools for non-hosted embedded systems that don't for the most part use float or complex and do use IEC\ISO 18037. In embedded systems LVA's have a different problem. Run time memory allocation is viewed as potential failure mode that can cause the whole system to fail. (Backed by some spectacular failures)
I think that some refinements to the proposal needs to be considered. Now may the time to re-visit some of the implementation defined specifications. We have targeted 28 processors and many of implementation defined issues probably could be defined with very little impact on code generation. I suspect that most of the compiler developers in WG-14 would agree on the implementation of most of the implementation defined parts of the standard
The proposal also opens (for us) the idea of a conforming C compiler that has some specific implementation part that is non conforming. For example two of our compilers have non standard floating point implementations so that the hardware may be better used, the remaining parts could be easily validated.
Michal Nazarewicz wrote: > II *Named Arguments* > 7. Named arguments would have to be specified using their name, thus, > with earlier `message()` declaration, the following would be > invalid:
While the general idea about named argument is interesting, I do not like that point.
It requires *both* the prototypes (part of the implementation of a library, usually as a .h) and the actual use to be in sync, that is using either the C90-style prototypes and function calls *or* the new-syntax prototypes and function calls.
As a consequence, this prevents this new feature to be used for the standard library, since it would break more than 90% of present day code (strangely, code using old-style definitions would still work); the same argument applies to any existing library, it would cause integration of it to require a rewriting of all the code which use it, thus creating a new API; I see it as a hint the feature does not integrate smoothly.
This problem also backfires the implementation. You said
> 4. The name of the argument would become part of a function's > prototype thus the following would be illegal:
> #v+ > void f1(int .bar); > void f1(int .baz); /* different name */ > void f2(int bar); > void f2(int .bar); /* unnamed vs. unnamed */ > #v-
So, assuming we have
/* header.h */ void f1(int .bar);
What the actual implementation of f1 would look like? I foresee two solutions: 1) in the grand tradition of C preprocessor hacks, header.h really is
/* header.h */ #ifndef _ #define _(p) p #endif
void f1 _((int .bar));
and then header.c would look like:
/* header.c */ #define _(p) () /* prevent the prototypes to come in */ #include "header.h" /* but get the structures and typedefs*/
void f1 (int bar) { // ... details omitted
2) additionnally to the proposal, arguments in the form .bar can be aliased in some way in the function definition; something along the lines of (== is just a placeholder, insert any symbol you prefer)
/* header.c */ #include "header.h"
void f1 (int foo == .bar) { // ... and then the code uses "foo" as parameter
(Of course "foo" can be actually spelled "bar".)
Neither solution I find attractive (yes, it is an understatement).
A third solution is to use .bar in the function definition body as well; it definitively looks strange to me, and I notice you did not provide examples. Also it could require a more complex parsing, and potential conflicts; feel free to write the yacc grammar which show me wrong.
As a bottom line, I believe the general point of the charters about "inventions" still stands here. If this seems a good idea to some people, it is urgent to actually implement it and to let people use it to some point. About overloading for example, we all know of implementations, and I believe there have already been talks in the committee about that idea (and if it is definitively discarded, it should been made clearer). Your idea about default argument have already implementations too (and C++ compatibility, at least I hope so), so people will have clear ideas too. This one about named argument passing on the other side is a new syntax, so it ought to be implemented to see if it works really.
As with several similar syntaxes, unnamed arguments should go first, in correct order; obviously, there is a defect with varargs functions, whose (also unnamed) arguments are to be put at the end, as in
format("we are out of %s, wants %d more", .level = LVL_WARN, .colour = WHITE, /*.sound omitted*/ resource_name, lack);
which is definitively ugly. It is just writing down here without actual experiment, so the point about potential parsing problem above applies here too. Just more food for thought.
jacob navia <ja...@spamsink.net> writes: > Morris Keesan a écrit : > > On Mon, 19 Apr 2010 06:03:54 -0400, jacob navia <ja...@nospam.org> wrote:
> >> ALl casts are conversions from one type to another. > > (char *)"Oh, really?" > > C99 6.5.4, paragraph 4, third sentence: "A cast that specifies no > > conversion has no effect on the type or value of an expression."
> That CONFIRMS what I said: if there is no conversion nothing happens!
No, it flatly contradicts what you said. You said that *all* casts are conversions from one type to another. Morris produced a cast that is not a conversion from one type to another.
> THEN
> All casts are conversions. When there is no conversion there is no effect.
No, not all casts are conversions. We see here a cast that is not a conversion.
> You can go on splitting hairs of course, it is a national sport here
Ok, the existence of casts that do not specify conversions is not a huge deal. The standard could just as easily have described this as a conversion from a type to the same type. You were *nearly* right, and I didn't notice the special case myself.
But you made the claim in response to something I wrote, in which I pointed out that there's no such thing as an "implicit cast"; rather, the OP was really talking about *implicit conversions*. Your claim, even if it were true, did not address my point.
To summarize:
A cast explicitly specifies a conversion, except in the special case where the specified type is the same as the operand type, and no conversion is necessary.
There is no such thing as an implicit cast.
A conversion, on the other hand, may be either explicit (specified by a cast) or implicit.
If i'm mistaken on any of these points, please demonstrate it.
-- 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"
> 1. It has been observed that calls to functions with many arguments > are somehow unreadable since it is hard to keep track of which > argument means what.
> 2. To mitigate this problem named arguments could be added to the > C language with a syntax similar to one used in structures and > union initialisation.
I used named arguments all the time, although I rely on the fact that GCC (like perhaps all compilers) will zero-initialize members not specified.
struct foo { int a, b; }; void foo(struct foo f); #define foo(...) foo((struct foo){ __VA_ARGS__ })
foo(.b = 42);
This technique could be ratified by specifying implicit zero initialization for auto object initializers and compound literals, and by allowing a member to be set twice (so that members could be pre-set by the macro to something other than zero).
> Michal Nazarewicz <min...@tlen.pl> wrote: > <snip> >> II *Named Arguments*
>> 1. It has been observed that calls to functions with many arguments >> are somehow unreadable since it is hard to keep track of which >> argument means what.
>> 2. To mitigate this problem named arguments could be added to the >> C language with a syntax similar to one used in structures and >> union initialisation. William Ahern <will...@wilbur.25thandClement.com> writes: > I used named arguments all the time, although I rely on the fact that GCC > (like perhaps all compilers) will zero-initialize members not specified.
> struct foo { int a, b; }; > void foo(struct foo f); > #define foo(...) foo((struct foo){ __VA_ARGS__ })
> foo(.b = 42);
This has an disadvantage especially on systems with a large number of registers where function arguments are passed via registers.
Also, can you use compound literals with non-const initialisers? I'd have to check.
-- Best regards, _ _ .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
Antoine Leca <r...@localhost.invalid> writes: > Michal Nazarewicz wrote: >> II *Named Arguments* >> 7. Named arguments would have to be specified using their name, thus, >> with earlier `message()` declaration, the following would be >> invalid:
> While the general idea about named argument is interesting, I do not > like that point.
> It requires *both* the prototypes (part of the implementation of a > library, usually as a .h) and the actual use to be in sync, that is > using either the C90-style prototypes and function calls *or* the > new-syntax prototypes and function calls.
> As a consequence, this prevents this new feature to be used for the > standard library, since it would break more than 90% of present day code > (strangely, code using old-style definitions would still work); the same > argument applies to any existing library, it would cause integration of > it to require a rewriting of all the code which use it, thus creating a > new API; I see it as a hint the feature does not integrate smoothly.
Yes, this is an issue but I think it's not as bad as you make it look like. First of all, the same function could be declared with named arguments in one translation unit and without in another. This mean that as long as you are using the same call convection in a single translation unit you are fine. So for instance, a library could look like this:
The problem arises when, for whatever reason, one wants to mix calling conventions. This can be somehow solved if we agree to use a different name for a new syntax, ie:
#v+ int sum(int, int); static inline int new_sum(int .a, int .b) { return sum(a, b);
}
#v-
Ideally it would be nice not to have to use tricks like this and choose whichever calling convection we feel like but that has it's own, in my opinion bigger, issues which I'll describe further down the post.
> This problem also backfires the implementation. You said
>> 4. The name of the argument would become part of a function's >> prototype thus the following would be illegal:
>> #v+ >> void f1(int .bar); >> void f1(int .baz); /* different name */ >> void f2(int bar); >> void f2(int .bar); /* unnamed vs. unnamed */ >> #v-
> So, assuming we have
> /* header.h */ > void f1(int .bar);
> What the actual implementation of f1 would look like? > I foresee two solutions: > 1) in the grand tradition of C preprocessor hacks, header.h really is
> /* header.c */ > #define _(p) () /* prevent the prototypes to come in */ > #include "header.h" /* but get the structures and typedefs*/
> void f1 (int bar) > { > // ... details omitted
> 2) additionnally to the proposal, arguments in the form .bar can be > aliased in some way in the function definition; something along the > lines of (== is just a placeholder, insert any symbol you prefer)
> /* header.c */ > #include "header.h"
> void f1 (int foo == .bar) > { > // ... and then the code uses "foo" as parameter
> (Of course "foo" can be actually spelled "bar".)
> Neither solution I find attractive (yes, it is an understatement).
> A third solution is to use .bar in the function definition body as well; > it definitively looks strange to me, and I notice you did not provide > examples. Also it could require a more complex parsing, and potential > conflicts; feel free to write the yacc grammar which show me wrong.
I don't see your point here. If the prototype is
#v+ void f1(int .bar);
then the definition would have to be:
void f1(int .bar) { /* ... */
}
#v-
I also do not see big problem in defining grammar. It's just an optional dot prior to formal argument name.
> As a bottom line, I believe the general point of the charters about > "inventions" still stands here. If this seems a good idea to some > people, it is urgent to actually implement it and to let people use it > to some point. About overloading for example, we all know of > implementations, and I believe there have already been talks in the > committee about that idea (and if it is definitively discarded, it > should been made clearer). Your idea about default argument have already > implementations too (and C++ compatibility, at least I hope so), so > people will have clear ideas too. This one about named argument passing > on the other side is a new syntax, so it ought to be implemented to see > if it works really.
> By the way, I have thought of a different syntax:
message(.msg = "An error", .colour = RED, .level = LVL_ERROR); /* an error at the point of usage call */ #v-
And thus this is why I proposed the names to become part of the prototype when the new syntax is used in prototype and only then the argument could be passed as named.
> As with several similar syntaxes, unnamed arguments should go first, in > correct order; obviously, there is a defect with varargs functions, > whose (also unnamed) arguments are to be put at the end, as in
> format("we are out of %s, wants %d more", > .level = LVL_WARN, .colour = WHITE, /*.sound omitted*/ > resource_name, lack);
> which is definitively ugly. It is just writing down here without actual > experiment, so the point about potential parsing problem above applies > here too. Just more food for thought.
This is exactly why named arguments would be required to be called by name so it's always clear which argument is which.
Again I don't see your point about parsing problems:
-- Best regards, _ _ .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
Michal Nazarewicz <min...@tlen.pl> wrote: > > Michal Nazarewicz <min...@tlen.pl> wrote: > > <snip> > >> II *Named Arguments*
> >> 1. It has been observed that calls to functions with many arguments > >> are somehow unreadable since it is hard to keep track of which > >> argument means what.
> >> 2. To mitigate this problem named arguments could be added to the > >> C language with a syntax similar to one used in structures and > >> union initialisation. > William Ahern <will...@wilbur.25thandClement.com> writes: > > I used named arguments all the time, although I rely on the fact that GCC > > (like perhaps all compilers) will zero-initialize members not specified.
> > foo(.b = 42); > This has an disadvantage especially on systems with a large number of > registers where function arguments are passed via registers.
Well, in truth I usually pass a pointer to the struct. But I do use this technique often. For example, creating an iterator construct for my DNS library:
This little trick blows up some compilers, such as the newly reinvigorated PCC. But as you can see, the resulting synthetic constructs are *very* *practical*. And it merely relies on novel compositions of existing C99 capabilities.
Now, perhaps the pre-processor magic is a little unslightly, and I would agree. But the truth is the vast majority of C code will always use traditional C patterns, even if the language was redefined to allow every feature request under the sun. So I think it's enough that some things _can_ be done, even if they're not source-code elegant; they don't necessarily require that the language provide the cleanest syntax, particularly if such requirements will in all likelihood be unmet.
Actually, now that I think about it, the above is well-defined, no matter GCC's complaints. Multiple initializers for the same member are allowed--the latter alone defining the value--and uninitialized sub-members are implicitly zero initialized. See 6.7.8(19) (9899:TC3 draft N1256) (my hardcopy of C99 is boxed up). I suppose my confusion has been with 6.7.8(9), which says unnamed members have indefined value. I guess the import is that all top-level structure members should be explicitly initialized; which is okay with me considering that they can be named in a subsequent initialization (i.e. from a __VA_ARGS__ in the macro construct above).
> Also, can you use compound literals with non-const initialisers? I'd > have to check.
Yes. This is allowed if occuring inside the body of a function.
int a = 3, b = 2, c = 1; int *p = (int [3]){ a, b, c };
But you can't do:
int a = 3, b = 2, c = 1; int *p = (int [a]){ a, b, c };
But you can do:
int a = 3, b = 2, c = 1; int *p = (int []){ a, b, c };
In other words, you can't mix VLA and compound literal constructs. See 6.5.2.5.
>> On 2010-04-19, jacob navia <ja...@spamsink.net> wrote: >>> The feature is not mandatory, it suffices to define a symbol and >>> there, no thread support. > Seebs <usenet-nos...@seebs.net> writes: >> So what? It's still unambiguously new feature work in the standard.
>> Of course not everything becomes mandatory. Keith Thompson <ks...@mib.org> writes: > And in this particular case, the feature will be optional *only* if > P.J. Plauger's proposal
> is accepted. As of the N1425 draft, threading is just another > language/library feature, with no indication that it's optional for > hosted implementations.
Personally, I would go for something I think is more generic, which is a "_Has" (or #has if you will) preprocessor operator, ie:
#if _Has <stdatomic.h> # include <stdatomic.h> #else # error This program requires stdatomic.h #endif
a shorthand #ifhas could be provided as well.
This would be more generic in such a way that libraries not covered by the standard could be checked as well, ie.:
#ifhas <some-funky-library.h> # include <some-funky-library.h> #else /* ... provide a simpler, inferior implementation ... */ #endif
-- Best regards, _ _ .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
>>> Michal Nazarewicz <min...@tlen.pl> wrote: >>>> This has an disadvantage especially on systems with a large number >>>> of registers where function arguments are passed via registers. William Ahern <will...@wilbur.25thandClement.com> writes: > Actually, it just occurred to me that modern ABIs can pass some > structures via registers. Passing a pointer is thus less efficient.
Can you point to some document that describes that? I don't see how this can be done. In particular one can do something like:
which would imply that the structure would have to be placed in the memory. As such, I don't see how some of it's elements can be passed via registers.
-- Best regards, _ _ .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
Michal Nazarewicz <min...@tlen.pl> wrote: > William Ahern <will...@wilbur.25thandClement.com> writes: > > Michal Nazarewicz <min...@tlen.pl> wrote: <snip> > >> This has an disadvantage especially on systems with a large number of > >> registers where function arguments are passed via registers.
> > Well, in truth I usually pass a pointer to the struct. > The same problem. So even though I admit it's an useful technique (and > in fact I've been wondering about the use of compound literals for > exactly that purpose) but it would be so much better if we had compiler > support for such a feature.
Actually, it just occurred to me that modern ABIs can pass some structures via registers. Passing a pointer is thus less efficient (though efficiency is not why I do it). This leaves open the question of whether larger structures are passed on the stack completely, or just the part that overflows.
William Ahern <will...@wilbur.25thandClement.com> writes: > Michal Nazarewicz <min...@tlen.pl> wrote: >> > Michal Nazarewicz <min...@tlen.pl> wrote: >> > <snip> >> >> II *Named Arguments*
>> >> 1. It has been observed that calls to functions with many arguments >> >> are somehow unreadable since it is hard to keep track of which >> >> argument means what.
>> >> 2. To mitigate this problem named arguments could be added to the >> >> C language with a syntax similar to one used in structures and >> >> union initialisation.
>> William Ahern <will...@wilbur.25thandClement.com> writes: >> > I used named arguments all the time, although I rely on the fact that GCC >> > (like perhaps all compilers) will zero-initialize members not specified.
>> This has an disadvantage especially on systems with a large number of >> registers where function arguments are passed via registers.
> Well, in truth I usually pass a pointer to the struct.
The same problem. So even though I admit it's an useful technique (and in fact I've been wondering about the use of compound literals for exactly that purpose) but it would be so much better if we had compiler support for such a feature.
> Now, perhaps the pre-processor magic is a little unslightly, and I would > agree. But the truth is the vast majority of C code will always use > traditional C patterns, even if the language was redefined to allow every > feature request under the sun. So I think it's enough that some things _can_ > be done, even if they're not source-code elegant; they don't necessarily > require that the language provide the cleanest syntax, particularly if such > requirements will in all likelihood be unmet.
I don't fully agree. If the feature is useful it will became used and as times goes by more and more often. The "inline" keyword or names in initialisation list (the { .foo = ... }, would have to check how it's called) are an example of that.
-- Best regards, _ _ .o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o ..o | Computer Science, Michal "mina86" Nazarewicz (o o) ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
Michal Nazarewicz <min...@tlen.pl> writes: > >>> Michal Nazarewicz <min...@tlen.pl> wrote: > >>>> This has an disadvantage especially on systems with a large number > >>>> of registers where function arguments are passed via registers.
> William Ahern <will...@wilbur.25thandClement.com> writes: > > Actually, it just occurred to me that modern ABIs can pass some > > structures via registers. Passing a pointer is thus less efficient.
> Can you point to some document that describes that? I don't see how > this can be done. In particular one can do something like:
> which would imply that the structure would have to be placed in the > memory. As such, I don't see how some of it's elements can be passed > via registers.
It's the same as passing any parameter in a register:
void foo(int arg) { int *argp = &arg;
}
The parameter passing convention might specify that a parameter of type int (or of a sufficiently small struct type) is passed in a certain register. If the function doesn't refer to the address of the parameter, it can stay in the register. If it does, it has to be copied to an addressible memory location.
This assume that registers aren't addressible. On some systems, they might be. The implementation merely has to ensure that the program's visible behavior matches the standard's requirements.
-- 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"