Are literals objects?

S

SasQ

Hello.

I wonder if literal constants are objects, or they're only
"naked" values not contained in any object?
I have read that literal constants may not to be allocated
by the compiler. If the Standard is saying that "object is
a region of storage", I deduce from that that literal constants
aren't objects because they may not be alocated as regions of
storage in the memory.

The Standard itself doesn't tell anything if literal constants
are objects or not [at least I haven't found anything]. It
only says that literal constants are expressions.

Are my thoughts correct?

I'm asking about this because some person told me that literal
constants are objects and that the following code prooves it:

const int& x = 7;
std::cout << x;

He said that it's an object because it is possible to set a
constant reference to it. Who's right here?
 
M

Me

Hello.

I wonder if literal constants are objects, or they're only "naked"
values not contained in any object? I have read that literal constants
may not to be allocated by the compiler. If the Standard is saying that
"object is a region of storage", I deduce from that that literal
constants aren't objects because they may not be alocated as regions of
storage in the memory.

I do not consider literal constants to be objects. Right or wrong, I
believe an object must have attributes and exhibit behavior: fields and
methods. A literal constant only has a field value and therefore has no
meaning unless it is used in a particular context.
 
G

Gianni Mariani

SasQ said:
Hello.

I wonder if literal constants are objects, or they're only
"naked" values not contained in any object?
I have read that literal constants may not to be allocated
by the compiler. If the Standard is saying that "object is
a region of storage", I deduce from that that literal constants
aren't objects because they may not be alocated as regions of
storage in the memory.

The Standard itself doesn't tell anything if literal constants
are objects or not [at least I haven't found anything]. It
only says that literal constants are expressions.

Are my thoughts correct?

Why do you care ?
I'm asking about this because some person told me that literal
constants are objects and that the following code prooves it:

const int& x = 7;

That says create a temporary int from a literal 7 and bind a reference to x.
std::cout << x;

Pass the value of x to operator<<.

In this case, the compiler is quite free to allocate no storage
whatsoever for x or the int it is pointing to. I would make a wager
that some compilers would treat that code exactly the same as it would.

std::cout << int(7);
He said that it's an object because it is possible to set a
constant reference to it. Who's right here?

A const reference allows the compiler to create a temporary object for
any kind of type that can be constructed from a literal 7.

i.e.

struct A
{
A( int );
};

const A & a = 1;

How does this "prove" anything and why would we care ?
 
I

Ian Collins

SasQ said:
Hello.

I wonder if literal constants are objects, or they're only
"naked" values not contained in any object?

If they were objects, they would have an address.
 
V

Victor Bazarov

Ian said:
If they were objects, they would have an address.

int main()
{
const int& x = 7;
return &x == 0;
}

Now, whose address I just compared to 0? Literal's? I am
not sure that's _not_ so. I wonder if there is a way to
prove it one way or the other.

V
 
I

Ian Collins

Victor said:
int main()
{
const int& x = 7;

Doesn't that create a temporary int with a value of 7 and assign its
address to x?
return &x == 0;
}

Now, whose address I just compared to 0? Literal's? I am
not sure that's _not_ so. I wonder if there is a way to
prove it one way or the other.
Well you can't write

const int* p = &7;

and I can't think of anything else that is considered an object that
doesn't have an address.
 
V

Victor Bazarov

Ian said:
Doesn't that create a temporary int with a value of 7 and assign its
address to x?

Uh... Isn't compiler allowed to optimize away creation of the
temporary? said:
Well you can't write

const int* p = &7;

Well, here you're splitting hairs. The address-of operator cannot
be used on a literal _syntactically_. It requires the expression
following the '&' to be an lvalue expression (which a literal isn't).
and I can't think of anything else that is considered an object that
doesn't have an address.

Right. By definition an object is a region of storage [that has
an address]. If the program contains '7', where is it stored? Is
it stored anywhere? If it is, doesn't that mean it has some address
(very likely contiguous) and therefore is an object (by definition)?

V
 
I

Ian Collins

Victor said:
Well, here you're splitting hairs. The address-of operator cannot
be used on a literal _syntactically_. It requires the expression
following the '&' to be an lvalue expression (which a literal isn't).
So can we say if it isn't an lvalue, it isn't an object?
and I can't think of anything else that is considered an object that
doesn't have an address.

Right. By definition an object is a region of storage [that has
an address]. If the program contains '7', where is it stored? Is
it stored anywhere? If it is, doesn't that mean it has some address
(very likely contiguous) and therefore is an object (by definition)?
By that definition, if( a=b ) is an object because the code that
implements it lives in addressable memory!

It's very likely that an assignment from constant expression is
represented as an immediate mode instruction, so at assembly level, it
isn't addressable. On a typical machine that is, it probably is
addressable on a DS9000.
 
A

Alf P. Steinbach

* Victor Bazarov:
int main()
{
const int& x = 7;
return &x == 0;
}

Now, whose address I just compared to 0? Literal's? I am
not sure that's _not_ so. I wonder if there is a way to
prove it one way or the other.

What "it" do you want to prove?

Here's the address of a literal:

#include <iostream>
void showAddress( void const* p ) { std::cout << p << std::endl; }
int main() { showAddress( "very literal string" ); }

On the other hand, the literal 7, if used in a program, might not even
exist in the machine code, because the compiler might generate machine
code that produces the same effect as using the number would have had.

Thus, some literals are objects and some are not.

And where it doesn't matter, it depends much on the compiler.
 
J

James Kanze

I wonder if literal constants are objects, or they're only
"naked" values not contained in any object?
I have read that literal constants may not to be allocated
by the compiler. If the Standard is saying that "object is
a region of storage", I deduce from that that literal constants
aren't objects because they may not be alocated as regions of
storage in the memory.

You're sort of right, but the issue is not really that clear.
The C++ (and the C) standard describe the results of expressions
as being lvalues or rvalues. An lvalue always refers to an
object; there's no doubt about that. An rvalue normally only
refers to an object if it has class type. But there are
contexts where an rvalue ends up being treated as an lvalue,
e.g. when it is bound to a const reference. In those cases, the
compiler is required to create an "object" to hold the value, in
order to do the binding.
The Standard itself doesn't tell anything if literal constants
are objects or not [at least I haven't found anything].

It does so indirectly. No literal constants have class type, so
a literal constant is an object if and only if it is an lvalue.
String literals are lvalues; other literals aren't.
It only says that literal constants are expressions.
Are my thoughts correct?
I'm asking about this because some person told me that literal
constants are objects and that the following code prooves it:
const int& x = 7;
std::cout << x;
He said that it's an object because it is possible to set a
constant reference to it. Who's right here?

According to the standard, the literal constant 7 is NOT an
object. The compiler creates a temporary object to hold it, and
binds the reference to this.

Note, however, that there are different ways of expressing the
same thing. The above is the way it is expressed in the
standard; other ways can be imagined.
 
J

James Kanze

[...]
On the other hand, the literal 7, if used in a program, might not even
exist in the machine code, because the compiler might generate machine
code that produces the same effect as using the number would have had.

Formally, that's true for objects as well. As long as the
generated code produces the correct observable behavior, the
compiler can do anything it pleases. (A simple example might be
to unwind a short loop, eliminating the loop control variable.
Which definitly is an object.)
Thus, some literals are objects and some are not.

According to the standard, string literals are objects, and
other literals aren't.
And where it doesn't matter, it depends much on the compiler.

The standard defines very clearly what it means by object. It
also states explicitly that lvalues designate objects, and
rvalues don't, unless they have class type. It also states that
when binding an rvalue to a const reference, the compiler
creates a temporary object with the correct value (and that
attempting to modify that temporary object, except for mutable
fields in an object of class type, is undefined behavior).

So if I write:
int const& i = 7 ;
7 is not an object, but the compiler is required to create a
temporary object to hold it.

After that, the "as if" rule and optimization come into play;
whether the object ever physically exists is irrelevant, as
long as the observable behavior is unchanged. (And of course,
if the program contains undefined behavior elsewhere, e.g. by
attempting to modify the 7, the compiler can do anything it
pleases.)

--
 
A

Alf P. Steinbach

* James Kanze:
[...]
On the other hand, the literal 7, if used in a program, might not even
exist in the machine code, because the compiler might generate machine
code that produces the same effect as using the number would have had.

Formally, that's true for objects as well.

Not really, no: with regard to what I intended to convey, you're
confusing existential quantifier with universal quantifier.

But I'm not perfect so I didn't express it pereflcty.

Read the "in a program" as "in any program".


[snip]
According to the standard, string literals are objects, and
other literals aren't.

Chapter & verse for the "other literals arent't", please.

The standard defines very clearly what it means by object.

No, it doesn't define the notion of object clearly, at all.

First, the general definition of object lists the ways to create objects
as definitions, new-expressions and temporaries, which would exclude
string literals, which have static storage duration.

Second, it doesn't define "region" and is a bit inconsistent with regard
to how scattered in bits & pieces an object may be. Instead of simply
and clearly defining "region" as a contiguous sequence of bytes, and
adding suitable wording to the definition of object, it attempts to use
the usual meaning of "region" in general but hold the door open for
non-contiguous region. It's very, very, very silly & unclear.

It
also states explicitly that lvalues designate objects, and
rvalues don't, unless they have class type.

That seems to contradict earlier statement of string literals as object;
consider

int main() { &"Hello"; }

I'm just noting the apparent contradiction.

Regarding whether the code above /should/ compile, Comeau accepts it.

It also states that
when binding an rvalue to a const reference, the compiler
creates a temporary object with the correct value (and that
attempting to modify that temporary object, except for mutable
fields in an object of class type, is undefined behavior).

Well, "creates a temporary": ITYM "any number of temporaries". But as I
understand it that rule will be changed in C++0x to allow temporaries of
class with no copy constructor to be passed to reference to const formal
argument. Which is generally nice.
 
G

Greg Comeau

I wonder if literal constants are objects, or they're only
"naked" values not contained in any object?
I have read that literal constants may not to be allocated
by the compiler. If the Standard is saying that "object is
a region of storage", I deduce from that that literal constants
aren't objects because they may not be alocated as regions of
storage in the memory.

The Standard itself doesn't tell anything if literal constants
are objects or not [at least I haven't found anything]. It
only says that literal constants are expressions.

Are my thoughts correct?

For many people, it's like obscenity, they know it when you see it,
but doesn't ask them to define it :)

I've never been comfortable with this part of the Standard,
of Standard C or of Standard C++, but that could just be me.
IMO, it *is* confusing to talk about region of storage and then
say but not all regions :) or then talk about the distinguishment
via lvalues and rvalues. Again, this could just be me.
I'm asking about this because some person told me that literal
constants are objects and that the following code prooves it:

const int& x = 7;
std::cout << x;

He said that it's an object because it is possible to set a
constant reference to it. Who's right here?

The problem here is that it's not providing a reference to
the 7, but instead make a reference to an unnamed temporary
that gets established behind the scenes. Of course, this just
deepens the issues, with a claim then that the the temporary is
an object. The related problem is that normally one would
consider an object something you can touch, usually reinforced
by say "aha, I can take it's address, so therefore I KNOW it exists!",
but that only goes so far, in many cases. And then there's also
the case of optimizations.

I'm not trying to say nothing can be said pro or con about
literals being objects; IMO most are not as defined by the
Standard no matter how "we" may feel about it. 7 is not an
object as defined by Standard C++ AFAIK.
 
G

Greg Comeau

Formally, that's true for objects as well. As long as the
generated code produces the correct observable behavior, the
compiler can do anything it pleases. (A simple example might be
to unwind a short loop, eliminating the loop control variable.
Which definitly is an object.)

Agreed. We should all remember that the Standard defines an abstract
machine that objects live in. In real machines, the object need not
actually exist so long as the rest of the semantics are retained.
But that does not change what an object is or isn't, although this
can be confusing.
 
S

SasQ

Dnia Fri, 06 Apr 2007 13:03:14 +1200, Ian Collins napisa³(a):
Well you can't write

const int* p = &7;

You can't write

&7;

also. It's because 7 is an r-value, and it's impossible
to take an address of an r-value. But you can write:

&"abcdef";

because string literals are l-values [as the only exception].
 
G

Greg Comeau

* James Kanze:

That seems to contradict earlier statement of string literals as object;
consider

int main() { &"Hello"; }

I'm just noting the apparent contradiction.

Regarding whether the code above /should/ compile, Comeau accepts it.

Not sure what you mean. A string literal reflects a few things
including at some point an array of chars.

So, you should be able to take its address. ??
 
S

SasQ

Dnia Thu, 05 Apr 2007 21:13:28 -0400, Victor Bazarov napisa³(a):
Well, here you're splitting hairs. The address-of operator
cannot be used on a literal _syntactically_. It requires the
expression following the '&' to be an lvalue expression
(which a literal isn't).

Some literals are [vide: string literals].
Right. By definition an object is a region of storage [that has
an address]. If the program contains '7', where is it stored?
Is it stored anywhere?

I think it might be stored somewhere, but doesn't have to be
[ie. the compiler may hold the value 7 in its symbol table only,
it might be convoluted into some assembly code, it might be
stored in a register which isn't addressable, and it might
generate that value directly in a register without placing it
in code space if it's faster]. So, I think the reason to not
taking addresses of r-values was that they're not necessary
stored in "storage memory" [addressable memory]. Some r-values
may be stored, but not all, so we can't assume they're stored.

Literals are r-values and some expressions [yielding temporary
objects] are r-values too, so it's impossible to get their addresses.
The only exception to that rule are string literals, which are
always stored in static memory and it's possible to take their
addresses for the reasons of compatibility with "ye olde C".

I think I'm right in my thoughts, but I want to make sure.
 
S

SasQ

Dnia Fri, 06 Apr 2007 14:27:08 +1200, Ian Collins napisa³(a):
The address-of operator cannot be used on a literal _syntactically_.
It requires the expression following the '&' to be an lvalue
expression (which a literal isn't).

So can we say if it isn't an lvalue, it isn't an object?
[...]
By that definition, if( a=b ) is an object because the code that
implements it lives in addressable memory!

I think it's that kind of "irreversible logic" problem ;J
All objects are regions of storage [as defined by Standard],
but otherwise is not always true [not every region of storage
is an object]. But I'm curious too what is the right answer.
 
V

Victor Bazarov

SasQ said:
[..]
Literals are r-values and some expressions [yielding temporary
objects] are r-values too, so it's impossible to get their addresses.

We're going off on a tangent here, but objects of class types have
addresses even if they are r-values. Behold:

#include <iostream>
struct foo {
void bar() { std::cout << this << std::endl; }
};
int main() {
std::cout << "Temporary at " << foo().bar();
}
The only exception to that rule are string literals, which are
always stored in static memory and it's possible to take their
addresses for the reasons of compatibility with "ye olde C".

I think I'm right in my thoughts, but I want to make sure.

I am not sure, but maybe you're only talking built-in types.

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top