Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #23384 > unrolled thread
| Started by | nroberts <roberts.noah@gmail.com> |
|---|---|
| First post | 2012-07-18 18:58 -0700 |
| Last post | 2012-07-19 08:57 -0700 |
| Articles | 6 — 4 participants |
Back to article view | Back to comp.lang.c
Taking address of struct temporary nroberts <roberts.noah@gmail.com> - 2012-07-18 18:58 -0700
Re: Taking address of struct temporary Keith Thompson <kst-u@mib.org> - 2012-07-18 19:27 -0700
Re: Taking address of struct temporary nroberts <roberts.noah@gmail.com> - 2012-07-19 08:54 -0700
Re: Taking address of struct temporary Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-07-18 22:31 -0400
Re: Taking address of struct temporary Ike Naar <ike@sverige.freeshell.org> - 2012-07-19 06:31 +0000
Re: Taking address of struct temporary nroberts <roberts.noah@gmail.com> - 2012-07-19 08:57 -0700
| From | nroberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2012-07-18 18:58 -0700 |
| Subject | Taking address of struct temporary |
| Message-ID | <73b21861-a104-4d94-8d44-747adbfbb7b3@t1g2000pbl.googlegroups.com> |
I've been playing around with an object library and have run into an
inconsistency between using it under a C compiler and using it under a
C++ compiler.
I wanted a way to declare "objects" statically, meaning they exist as
constants. I did something like the following:
struct Object {
struct Class const* isa;
};
struct String_ {
struct Object const _;
char const* buf;
int len;
};
extern void* __X_STR;
#define xstr(X) &(struct String_){ { __X_STR }, X, sizeof(X) };
The '__X_STR' variable is defined statically in a C file.
Later I can do the following:
void* s = xstr("Hello World!);
This works fine under gcc but pitches a fit under g++ about taking the
address of a temporary.
In C++ the expression (struct String_)... is in fact a temporary. I
expected, but do not know, that in C this would be an object in static
memory. Thus in C++ I'm doing something illegal but in C maybe it's
perfectly fine.
Is this correct?
[toc] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-07-18 19:27 -0700 |
| Message-ID | <lnk3y0bi3h.fsf@nuthaus.mib.org> |
| In reply to | #23384 |
nroberts <roberts.noah@gmail.com> writes:
> I've been playing around with an object library and have run into an
> inconsistency between using it under a C compiler and using it under a
> C++ compiler.
>
> I wanted a way to declare "objects" statically, meaning they exist as
> constants. I did something like the following:
>
> struct Object {
> struct Class const* isa;
> };
>
> struct String_ {
> struct Object const _;
> char const* buf;
> int len;
> };
>
> extern void* __X_STR;
>
> #define xstr(X) &(struct String_){ { __X_STR }, X, sizeof(X) };
>
> The '__X_STR' variable is defined statically in a C file.
>
> Later I can do the following:
>
> void* s = xstr("Hello World!);
>
> This works fine under gcc but pitches a fit under g++ about taking the
> address of a temporary.
>
> In C++ the expression (struct String_)... is in fact a temporary. I
> expected, but do not know, that in C this would be an object in static
> memory. Thus in C++ I'm doing something illegal but in C maybe it's
> perfectly fine.
>
> Is this correct?
First of all, avoid creating identifiers that start with an underscore;
most of them are reserved to the implementation. (There's a bit more to
it than that, but "never create identifiers starting with _" is an
easier rule to remember.)
In C,
(struct String_){ ... }
is a compound literal. As C11 6.5.2.5p5 says (C99 is similar, if not
identical):
The value of the compound literal is that of an unnamed object
initialized by the initializer list. If the compound literal
occurs outside the body of a function, the object has static
storage duration; otherwise, it has automatic storage duration
associated with the enclosing block.
I don't think it's referred to as a *temporary*, but there is some
danger of letting a pointer to the object escape the object's scope.
<OT>
C++, even as of the new 2011 ISO standard, does not support compound
literals. They appear to be a g++ extension. You'll have to consult
the gcc documentation to find out how they behave.
</OT>
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | nroberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2012-07-19 08:54 -0700 |
| Message-ID | <5a027e58-ee71-478e-8bb2-2e99b6b30e8c@h20g2000yqe.googlegroups.com> |
| In reply to | #23385 |
On Jul 18, 7:27 pm, Keith Thompson <ks...@mib.org> wrote:
> nroberts <roberts.n...@gmail.com> writes:
> > I've been playing around with an object library and have run into an
> > inconsistency between using it under a C compiler and using it under a
> > C++ compiler.
>
> > I wanted a way to declare "objects" statically, meaning they exist as
> > constants. I did something like the following:
>
> > struct Object {
> > struct Class const* isa;
> > };
>
> > struct String_ {
> > struct Object const _;
> > char const* buf;
> > int len;
> > };
>
> > extern void* __X_STR;
>
> > #define xstr(X) &(struct String_){ { __X_STR }, X, sizeof(X) };
>
> > The '__X_STR' variable is defined statically in a C file.
>
> > Later I can do the following:
>
> > void* s = xstr("Hello World!);
>
> > This works fine under gcc but pitches a fit under g++ about taking the
> > address of a temporary.
>
> > In C++ the expression (struct String_)... is in fact a temporary. I
> > expected, but do not know, that in C this would be an object in static
> > memory. Thus in C++ I'm doing something illegal but in C maybe it's
> > perfectly fine.
>
> > Is this correct?
>
> First of all, avoid creating identifiers that start with an underscore;
> most of them are reserved to the implementation. (There's a bit more to
> it than that, but "never create identifiers starting with _" is an
> easier rule to remember.)
>
> In C,
>
> (struct String_){ ... }
>
> is a compound literal. As C11 6.5.2.5p5 says (C99 is similar, if not
> identical):
>
> The value of the compound literal is that of an unnamed object
> initialized by the initializer list. If the compound literal
> occurs outside the body of a function, the object has static
> storage duration; otherwise, it has automatic storage duration
> associated with the enclosing block.
>
> I don't think it's referred to as a *temporary*, but there is some
> danger of letting a pointer to the object escape the object's scope.
>
> <OT>
> C++, even as of the new 2011 ISO standard, does not support compound
> literals. They appear to be a g++ extension. You'll have to consult
> the gcc documentation to find out how they behave.
> </OT>
Thanks for this. Answers everything I needed to know to move
forward. This helps a great deal and lies in complete contrast to Mr.
Sosman's nastiness, which didn't even answer anything. Your answer is
much appreciated.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-07-18 22:31 -0400 |
| Message-ID | <ju7rie$83q$1@dont-email.me> |
| In reply to | #23384 |
On 7/18/2012 9:58 PM, nroberts wrote:
> I've been playing around with an object library and have run into an
> inconsistency between using it under a C compiler and using it under a
> C++ compiler.
This is about as surprising as if you'd found an inconsistency
when running the same code through a COBOL compiler. C and C++ are
different languages. They are similar in many points, but the only
purpose of those similarities is to entrap the unwary.
> I wanted a way to declare "objects" statically, meaning they exist as
> constants. I did something like the following:
"Something like." O frabjous day. O diem praeclarum. Whoopee.
> struct Object {
> struct Class const* isa;
> };
>
> struct String_ {
> struct Object const _;
> char const* buf;
> int len;
Aside: `size_t' might be better here.
> };
>
> extern void* __X_STR;
Reserved identifier. If the implementation attaches some
unexpected meaning to it (and no, it's not required to document
the fact), that's your tough luck for infringing its name space.
> #define xstr(X) &(struct String_){ { __X_STR }, X, sizeof(X) };
You probably don't want the semicolon.
> The '__X_STR' variable is defined statically in a C file.
Bad idea, as mentioned above.
> Later I can do the following:
>
> void* s = xstr("Hello World!);
Missing a quotation mark.
> This works fine under gcc but pitches a fit under g++ about taking the
> address of a temporary.
Well, no: "this" does not "work fine under gcc" because gcc
won't even compile it. "Something derivable from this" may be
working for you -- but if I've imagined a different "something"
than what you're actually using, my advice may do you little good.
Again, that's your tough luck.
> In C++ the expression (struct String_)... is in fact a temporary. I
> expected, but do not know, that in C this would be an object in static
> memory. Thus in C++ I'm doing something illegal but in C maybe it's
> perfectly fine.
>
> Is this correct?
It depends on where your `xstr' appears. If it's outside a
function the literal has static storage duration; inside, it has
automatic duration and vanishes when the enclosing block exits.
See 6.5.2.5p5.
--
Eric Sosman
esosman@ieee-dot-org.invalid
[toc] | [prev] | [next] | [standalone]
| From | Ike Naar <ike@sverige.freeshell.org> |
|---|---|
| Date | 2012-07-19 06:31 +0000 |
| Message-ID | <slrn3vfsk0faev.ke4.ike@sverige.freeshell.org> |
| In reply to | #23384 |
On 2012-07-19, nroberts <roberts.noah@gmail.com> wrote:
> I've been playing around with an object library and have run into an
> inconsistency between using it under a C compiler and using it under a
> C++ compiler.
>
> I wanted a way to declare "objects" statically, meaning they exist as
> constants. I did something like the following:
>
> struct Object {
> struct Class const* isa;
> };
>
> struct String_ {
> struct Object const _;
> char const* buf;
> int len;
> };
>
> extern void* __X_STR;
>
> #define xstr(X) &(struct String_){ { __X_STR }, X, sizeof(X) };
>
> The '__X_STR' variable is defined statically in a C file.
Elsethread is has been explained why __X_STR is not a well chosen name.
What has not been mentioned yet is that name mangling can be a problem.
You say the __X_STR variable is defined in a C file. If you refer to
it as plain extern in a C++ file the names will probably not match, and
you'll have to use
extern "C" void * __X_STR;
[toc] | [prev] | [next] | [standalone]
| From | nroberts <roberts.noah@gmail.com> |
|---|---|
| Date | 2012-07-19 08:57 -0700 |
| Message-ID | <7f81781a-cb12-4c99-a404-054181f98d01@d32g2000yqn.googlegroups.com> |
| In reply to | #23388 |
On Jul 18, 11:31 pm, Ike Naar <i...@sverige.freeshell.org> wrote: > On 2012-07-19, nroberts <roberts.n...@gmail.com> wrote: > > > I've been playing around with an object library and have run into an > > inconsistency between using it under a C compiler and using it under a > > C++ compiler. > [snip] > > Elsethread is has been explained why __X_STR is not a well chosen name. > What has not been mentioned yet is that name mangling can be a problem. > You say the __X_STR variable is defined in a C file. If you refer to > it as plain extern in a C++ file the names will probably not match, and > you'll have to use > > extern "C" void * __X_STR; Yeah, I'm doing that. Thanks. Only reason this turned up is I'm testing the library with Boost.Test so I'm having to familiarize myself with the many subtle differences between the languages.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web