468,463 Members | 2,053 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,463 developers. It's quick & easy.

Initialized arrays using new


This produces an initialized array to zero:

int *i = new int[100]() ;

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

But this doesn't initialize the array. The assembly output is identical.
What's going on?

int *i = new int[100] ;

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp
Aug 17 '06 #1
34 12598
John wrote:
This produces an initialized array to zero:

int *i = new int[100]() ;
What would this do?

int *i = new int[100](42) ;

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Aug 17 '06 #2
Phlip wrote:
John wrote:
>This produces an initialized array to zero:

int *i = new int[100]() ;

What would this do?

int *i = new int[100](42) ;
Produce a compiler error:

error C2075: 'Target of operator new()' : array initialization needs curly braces
Aug 17 '06 #3
John wrote:
>>This produces an initialized array to zero:

int *i = new int[100]() ;

What would this do?

int *i = new int[100](42) ;
Produce a compiler error:

error C2075: 'Target of operator new()' : array initialization needs curly
braces
I am aware that this assertion passes:

assert(0 == int());

but it looks like if 'new int[100](42)' cannot create an array of 100 ints
initialized to 42, then 'new int[100]()' is not the same as using new to
create an array of 100 'int()' constructions. It seems that the trailing
'()' is an artifact of 'new's status as a kind of function. You can say 'new
SimCity;' or 'new SimCity()'.

A language lawyer might find actual verbiage on the subject, but I would
just go with a 'std::vector' and 'std::fill()'.

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Aug 18 '06 #4
Phlip wrote:
John wrote:
>>>This produces an initialized array to zero:

int *i = new int[100]() ;

What would this do?

int *i = new int[100](42) ;
>Produce a compiler error:

error C2075: 'Target of operator new()' : array initialization needs curly
braces

I am aware that this assertion passes:

assert(0 == int());

but it looks like if 'new int[100](42)' cannot create an array of 100 ints
initialized to 42, then 'new int[100]()' is not the same as using new to
create an array of 100 'int()' constructions. It seems that the trailing
'()' is an artifact of 'new's status as a kind of function. You can say 'new
SimCity;' or 'new SimCity()'.

A language lawyer might find actual verbiage on the subject, but I would
just go with a 'std::vector' and 'std::fill()'.
I think you missed my original point, why do two different constructs that
produces two different set of results create the identical machine code?
This produces an initialized array to zero:

int *i = new int[100]() ; <-- notice the '()'.

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

But this doesn't initialize the array. The assembly output is identical.
What's going on?

int *i = new int[100] ; <-- this array is *not* initalized

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp
Aug 18 '06 #5

John wrote:

[snip]
I think you missed my original point, why do two different constructs that
produces two different set of results create the identical machine code?
This produces an initialized array to zero:
How do you know? Why do you think it was "initialized"? I mean, how
do you know that region of memory didn't, by coincidence, happen to
have zeros in it?
int *i = new int[100]() ; <-- notice the '()'.
[snip]

Best regards,

Tom

Aug 18 '06 #6
John wrote:
[..] why do two different constructs
that produces two different set of results create the identical
machine code?
What compiler is that?
This produces an initialized array to zero:
How do you know that it's initialised to 0?
>
int *i = new int[100]() ; <-- notice the '()'.

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp
This looks like contents of a function. Have you tried actually
_using_ the array contents? The optimiser can discard any code
that has no effect (like setting your array elements to 0).
>
But this doesn't initialize the array. The assembly output is
identical. What's going on?
Post C++ code, then we can talk.
>
int *i = new int[100] ; <-- this array is *not* initalized

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 18 '06 #7

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:nN******************************@comcast.com. ..
John wrote:
>[..] why do two different constructs
that produces two different set of results create the identical
machine code?

What compiler is that?
>This produces an initialized array to zero:

How do you know that it's initialised to 0?
>>
int *i = new int[100]() ; <-- notice the '()'.

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

This looks like contents of a function. Have you tried actually
_using_ the array contents? The optimiser can discard any code
that has no effect (like setting your array elements to 0).
>>
But this doesn't initialize the array. The assembly output is
identical. What's going on?

Post C++ code, then we can talk.
>>
int *i = new int[100] ; <-- this array is *not* initalized

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

V
On my system I tried this:
int* MyArray = new int[10];
std::cout << MyArray[0] << std::endl;
delete[] MyArray;

MyArray = new int[10]();
std::cout << MyArray[0] << std::endl;
delete[] MyArray;

MyArray = new int[10]();
std::cout << MyArray[0] << std::endl;
delete[] MyArray;

MyArray = new int[10];
std::cout << MyArray[0] << std::endl;
delete[] MyArray;

output was:
-842150451
0
0
-842150451

I then added a few more, didn't delete them til after they were all created,
displayed [2] instead of 0, etc.. but in all cases if the array was in the
syntax new int[10]() the values were always 0, other numbers otherwise
(curiously enough, I was always winding up with -842150451).

This would be a strong indication that it was, in fact, zero initializing
the array. I am not the OP but got curious myself.
Aug 18 '06 #8

"John" <Jo**@nospam.comwrote in message
news:Ag********************@tornado.southeast.rr.c om...
>
This produces an initialized array to zero:

int *i = new int[100]() ;

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

But this doesn't initialize the array. The assembly output is identical.
What's going on?
Have you looked at the assembly after this? Are you 100% sure that there
isn't some assembly after this iterating through the array and setting the
values to 0?

>
int *i = new int[100] ;

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

Aug 18 '06 #9
Jim Langston wrote:
On my system I tried this:
int* MyArray = new int[10];
std::cout << MyArray[0] << std::endl;
Just a note: The act of rvalue-ing an uninitialized integer is undefined.

(Question: Is this defined?

char f;
assert(0 == f || 0 != f);

I know it's undefined for 'int f'.)

You are correct that you can use this experiment to trivially inspect raw
memory, on most architectures. But the undefinity happens before you even
see the 0 or !0.

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Aug 18 '06 #10
Phlip wrote:
Jim Langston wrote:

>>On my system I tried this:
int* MyArray = new int[10];
std::cout << MyArray[0] << std::endl;


Just a note: The act of rvalue-ing an uninitialized integer is undefined.

(Question: Is this defined?

char f;
assert(0 == f || 0 != f);

I know it's undefined for 'int f'.)
In C it's undefined when f is an int, but well defined when f is any
flavor of char.
>
You are correct that you can use this experiment to trivially inspect raw
memory, on most architectures. But the undefinity happens before you even
see the 0 or !0.
But "undefined" doesn't mean "must not do what you expect." I know that
the C folks have spent a great deal of time discussing the possibility
of trap values, so I assume there are architectures where they exist,
but I haven't run into any. So it's not an issue I spend time worrying
about.
Aug 18 '06 #11
John posted:
This produces an initialized array to zero:

int *i = new int[100]() ;

The Standard guarantees this.

But this doesn't initialize the array. The assembly output is identical.
What's going on?

int *i = new int[100] ;

It appears that your compiler initialises all new'd memory to zero
(regardless of whether you ask it to). This is inefficient, yet doesn't
violate any constraits of the Standard.

Perhaps if you switch to Release Mode, it will remove this inefficiency.

--

Frederick Gotham
Aug 18 '06 #12
John schrieb:
>
This produces an initialized array to zero:

int *i = new int[100]() ;
Yes.
004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp
<Half-OT>
I don't see any initialization in the assembly code. Perhaups the operator
new does it.

Did you check if the array really is initialized to zero?

What compiler are you using? I think VC6.0 didn't do the zero
initialization is this case.
</>

--
Thomas
Aug 18 '06 #13
Whoa! My bad! I should have tested the code using more than one compiler.

This is the code:

int *i = new int[20]() ;
for ( int x = 0 ; x < 20 ; x++, cout << i[x] << " " ) ;
cout << endl ;
int *i2 = new int[20] ;
for ( int x = 0 ; x < 20 ; x++, cout << i2[x] << " ") ;
cout << endl ;

These are the results under Visual Studio C++ Express (latest version)

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -33686019
-842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451
-842150451 -842150451 -842150451 -842150451 -842150451 -842150451 -842150451
-842150451 -842150451 -842150451 -842150451 -842150451 -33686019

However, these are the results using BloodShed (version 4.9.9.2):

-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1414812757 (interesting that the last element differs)
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1414812757

So, for whatever reason, when I was inspecting the first few results of:

int *i = new int[array_size]()

using Visual Studio, it just happens that all elements of the array (except
for the last element). I didn't check out the entire array before posting my
original note. Dumb, dumb, dumb.

Using this code with Visual Studio, all elements of both arrays (except for
the last element in both cases) are zero.

int *i = new int[1000]() ;
for ( int x = 0 ; x < 1000 ; x++, cout << i[x] << " " ) ;
cout << endl ;
double *d = new double[1000]() ;
for ( int x = 0 ; x < 1000 ; x++, cout << d[x] << " " ) ;
cout << endl ;

I graded my "assignment" an 'A' for Assuming.
Aug 18 '06 #14
"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:fu*******************@news.indigo.ie...
It appears that your compiler initialises all new'd memory to zero
(regardless of whether you ask it to). This is inefficient, yet doesn't
violate any constraits of the Standard.

Perhaps if you switch to Release Mode, it will remove this inefficiency.
If the Debug Mode initializes uninitialized memory to 0, that's really poor
design; it makes code work when it really shouldn't. I would have thought a
better move would be to initialize all uninitialized memory to 0xdeadbeef...

Is this common behaviour for IDEs?

Philip

Aug 18 '06 #15
John schrieb:
Whoa! My bad! I should have tested the code using more than one compiler.

This is the code:

int *i = new int[20]() ;
for ( int x = 0 ; x < 20 ; x++, cout << i[x] << " " ) ;
cout << endl ;
int *i2 = new int[20] ;
for ( int x = 0 ; x < 20 ; x++, cout << i2[x] << " ") ;
cout << endl ;
Your loop is wrong. Put the output line between the ')' and the ';'. You
are accessing memory one past the array, which is undefined behaviour.
BloodShed (version 4.9.9.2):
This compiler seems to be not standard conformant.

--
Thomas
Aug 18 '06 #16
Philip Potter wrote:
"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:fu*******************@news.indigo.ie...
>It appears that your compiler initialises all new'd memory to zero
(regardless of whether you ask it to). This is inefficient, yet
doesn't violate any constraits of the Standard.

Perhaps if you switch to Release Mode, it will remove this
inefficiency.

If the Debug Mode initializes uninitialized memory to 0, that's
really poor design; it makes code work when it really shouldn't. I
would have thought a better move would be to initialize all
uninitialized memory to 0xdeadbeef...

Is this common behaviour for IDEs?
What does it have to do with IDEs? It's the compilers who are at
fault.

Actually they used to be, and was sometimes a source of trouble. I
do remember chasing down an uninitialised *double* in release mode
on a system with an emulator of FP coprocessor which fell over when
an uninitialised value was "loaded" into its "registers". In debug
mode everything, as you may have guessed, was fine because the same
double was zero-initialised.

At present, since *I* mostly deal with VC++, I know that only newly
allocated memory is initialised with 0xCC octets in debug and filled
with 0xDD on delete, but it only concerns free store. There can be
more, but, honestly, I am too busy to remember all those things.

You know, like they say, just do the right thing and everything is
going to be hunky-dory.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 18 '06 #17
In article <11*********************@p79g2000cwp.googlegroups. com>,
Thomas Tutone <Th***********@yahoo.comwrote:
>John wrote:
[snip]
>I think you missed my original point, why do two different constructs that
produces two different set of results create the identical machine code?
This produces an initialized array to zero:

How do you know? Why do you think it was "initialized"? I mean, how
do you know that region of memory didn't, by coincidence, happen to
have zeros in it?
>int *i = new int[100]() ; <-- notice the '()'.
If one has a standard conforming compiler, running in compliant mode,
then John is right that after new int[100]() that the array has
been 0 init'd. It won't be guaranteed w/o the ().
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in alpha!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 18 '06 #18
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:ec**********@news.datemas.de...
Philip Potter wrote:
If the Debug Mode initializes uninitialized memory to 0, that's
really poor design; it makes code work when it really shouldn't. I
would have thought a better move would be to initialize all
uninitialized memory to 0xdeadbeef...

Is this common behaviour for IDEs?

What does it have to do with IDEs? It's the compilers who are at
fault.
You're right, of course. (I've only ever seen a debug/release switch in
compilers attached to IDEs)
Actually they used to be, and was sometimes a source of trouble. I
do remember chasing down an uninitialised *double* in release mode
on a system with an emulator of FP coprocessor which fell over when
an uninitialised value was "loaded" into its "registers". In debug
mode everything, as you may have guessed, was fine because the same
double was zero-initialised.

At present, since *I* mostly deal with VC++, I know that only newly
allocated memory is initialised with 0xCC octets in debug and filled
with 0xDD on delete, but it only concerns free store. There can be
more, but, honestly, I am too busy to remember all those things.
That's good to know about.
You know, like they say, just do the right thing and everything is
going to be hunky-dory.
Heh. If I did the right thing all the time, I wouldn't have any need for
compiler warnings.

Philip

Aug 18 '06 #19
Jim Langston wrote:
"John" <Jo**@nospam.comwrote in message
news:Ag********************@tornado.southeast.rr.c om...
>>
This produces an initialized array to zero:

int *i = new int[100]() ;

004124B0 push ebp
004124B1 mov ebp,esp
004124B3 mov eax,dword ptr [count]
004124B6 push eax
004124B7 call operator new (411212h)
004124BC add esp,4
004124BF pop ebp

But this doesn't initialize the array. The assembly output is identical.
What's going on?

Have you looked at the assembly after this? Are you 100% sure that there
isn't some assembly after this iterating through the array and setting the
values to 0?


No, I wasn't 100% certain so I looked deeper into the disassembly code
produced from Visual Studio, and by golly, you are correct. This type (new
int[ARRAY_SIZE]()) does in fact call memset initializing the array to zero. 0
is pushed onto the stack in the call to memset.

// snippet from memset
// AL == 0 (value to be set), CX == 0xA (the size of the array)
102308CA shr ecx,2
102308CD je 102308D5
102308CF rep stos dword ptr es:[edi]

void testarray()
{
00411640 push ebp
00411641 mov ebp,esp
00411643 sub esp,10Ch
00411649 push ebx
0041164A push esi
0041164B push edi
0041164C lea edi,[ebp-10Ch]
00411652 mov ecx,43h
00411657 mov eax,0CCCCCCCCh
0041165C rep stos dword ptr es:[edi]
const int ARRAY_SIZE = 10 ;
0041165E mov dword ptr [ARRAY_SIZE],0Ah
int *i = new int[ARRAY_SIZE]() ;
00411665 mov dword ptr [ebp-104h],28h
0041166F mov eax,dword ptr [ebp-104h]
00411675 push eax
00411676 call operator new[] (4110EBh)
0041167B add esp,4
0041167E mov dword ptr [ebp-0F8h],eax
00411684 cmp dword ptr [ebp-0F8h],0
0041168B je testarray+73h (4116B3h)
0041168D mov ecx,dword ptr [ebp-104h]
00411693 push ecx
00411694 push 0
00411696 mov edx,dword ptr [ebp-0F8h]
0041169C push edx
0041169D call @ILT+155(_memset) (4110A0h) ***MEMSET HERE!***
004116A2 add esp,0Ch
004116A5 mov eax,dword ptr [ebp-0F8h]
004116AB mov dword ptr [ebp-10Ch],eax
004116B1 jmp testarray+7Dh (4116BDh)
004116B3 mov dword ptr [ebp-10Ch],0
004116BD mov ecx,dword ptr [ebp-10Ch]
004116C3 mov dword ptr [i],ecx
// for ( int x = 0 ; x < ARRAY_SIZE ; x++ )
// cout << i[x] << " " ;
// cout << endl ;
int *i2 = new int[ARRAY_SIZE] ;
004116C6 push 28h
004116C8 call operator new[] (4110EBh)
004116CD add esp,4
004116D0 mov dword ptr [ebp-0ECh],eax
004116D6 mov eax,dword ptr [ebp-0ECh]
004116DC mov dword ptr [i2],eax
// for ( int x = 0 ; x < ARRAY_SIZE ; x++ )
// cout << i2[x] << " " ;
// cout << endl ;
}
004116DF pop edi
004116E0 pop esi
004116E1 pop ebx
004116E2 add esp,10Ch
004116E8 cmp ebp,esp
004116EA call @ILT+435(__RTC_CheckEsp) (4111B8h)
004116EF mov esp,ebp
004116F1 pop ebp
004116F2 ret LEAVE FUNCTION. MEMSET NOT CALLED THIS TIME.
Aug 18 '06 #20
Pete Becker posted:
Phlip wrote:
>Jim Langston wrote:

>>>On my system I tried this:
int* MyArray = new int[10];
std::cout << MyArray[0] << std::endl;


Just a note: The act of rvalue-ing an uninitialized integer is
undefined.
>>
(Question: Is this defined?

char f;
assert(0 == f || 0 != f);

I know it's undefined for 'int f'.)

In C it's undefined when f is an int, but well defined when f is any
flavor of char.

Signed char may trap in C (it may also contain padding).

Signed char may NOT contain padding in C++ (although I'm not certain if it
can trap or not -- you never get a clear answer.)

--

Frederick Gotham
Aug 18 '06 #21
In article <fu*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:
>John posted:
>This produces an initialized array to zero:

int *i = new int[100]() ;


The Standard guarantees this.

>But this doesn't initialize the array. The assembly output is identical.
What's going on?

int *i = new int[100] ;


It appears that your compiler initialises all new'd memory to zero
(regardless of whether you ask it to). This is inefficient, yet doesn't
violate any constraits of the Standard.

Perhaps if you switch to Release Mode, it will remove this inefficiency.
It probably didn't actually do the zero new in the latter case
and happened to return a pointer to a block that was already zero'd.
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in alpha!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 18 '06 #22
Frederick Gotham wrote:
Pete Becker posted:

>>Phlip wrote:
>>>Jim Langston wrote:

On my system I tried this:
int* MyArray = new int[10];
std::cout << MyArray[0] << std::endl;
Just a note: The act of rvalue-ing an uninitialized integer is

undefined.
>>>(Question: Is this defined?

char f;
assert(0 == f || 0 != f);

I know it's undefined for 'int f'.)

In C it's undefined when f is an int, but well defined when f is any
flavor of char.

Signed char may trap in C (it may also contain padding).
6.2.6.1/5:

Certain object representations need not represent a value of the
object type. If the stored value has such a representation and
is read by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. If such a representation is
produced by a side effect that modifies all or any part of the
object by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. Such a representation is
called a trap representation. [emphasis added]

Reading and writing a value through any character type are both well
defined, i.e. they do not trap.
Aug 18 '06 #23
John wrote:
However, these are the results using BloodShed (version 4.9.9.2):

-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1414812757
(interesting that the last element differs)
Also note that barfing out your raw memory where others can see is a
security loophole! ;-)

--
Phlip
http://c2.com/cgi/wiki?ZeekLand <-- NOT a blog!!!
Aug 18 '06 #24
On Fri, 18 Aug 2006 16:08:13 GMT, "Phlip" <ph******@yahoo.comwrote:
>John wrote:
>However, these are the results using BloodShed (version 4.9.9.2):

-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1163005939
-1163005939 -1163005939 -1163005939 -1163005939 -1163005939 -1414812757
(interesting that the last element differs)

Also note that barfing out your raw memory where others can see is a
security loophole! ;-)
That's not what loophole means.
Aug 18 '06 #25

Is this related to the C++ feature where;

int x;

int y = int();

y is guaranteed to be initialized?

Tolga Ceylan

Aug 18 '06 #26
Pete Becker posted:

6.2.6.1/5:

Certain object representations need not represent a value of the
object type. If the stored value has such a representation and
is read by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. If such a representation is
produced by a side effect that modifies all or any part of the
object by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. Such a representation is
called a trap representation. [emphasis added]

Reading and writing a value through any character type are both well
defined, i.e. they do not trap.

But, in C, a signed char can still contain padding... right?

Is the above snippet from the C Standard, or the C++ Standard?

--

Frederick Gotham
Aug 18 '06 #27
Greg Comeau posted:
It probably didn't actually do the zero new in the latter case
and happened to return a pointer to a block that was already zero'd.

The assembly code was identical though -- so "new" must zero its memory by
default on that system... no?

--

Frederick Gotham
Aug 18 '06 #28
posted:
>
Is this related to the C++ feature where;

int x;

int y = int();

y is guaranteed to be initialized?

Yes, exactly that. Also:

class MyClass {
private:

int i;

public:

MyClass() : i() {}
};

--

Frederick Gotham
Aug 18 '06 #29
Frederick Gotham wrote:
Pete Becker posted:
>>6.2.6.1/5:

Certain object representations need not represent a value of the
object type. If the stored value has such a representation and
is read by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. If such a representation is
produced by a side effect that modifies all or any part of the
object by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. Such a representation is
called a trap representation. [emphasis added]

Reading and writing a value through any character type are both well
defined, i.e. they do not trap.

But, in C, a signed char can still contain padding... right?
I don't see how, given the constraints on the relationship between
signed and unsigned variants of the same type, and the requirement that
unsigned char have no padding. There's just no room. They're the same
size, and the sign bit takes up one bit. When the sign bit is 0, the
remaining value bits mean the same thing in both signed char and
unsigned char. Since there's no padding in an unsigned char, there's
nothing left to pad with for non-negative values of type signed char.
Is the above snippet from the C Standard, or the C++ Standard?
It was a reply to your

Signed char may trap in C (it may also contain padding).
It's from C99.
Aug 18 '06 #30

"Frederick Gotham" <fg*******@SPAM.comwrote in message
news:_w*******************@news.indigo.ie...
Greg Comeau posted:
>It probably didn't actually do the zero new in the latter case
and happened to return a pointer to a block that was already zero'd.


The assembly code was identical though -- so "new" must zero its memory by
default on that system... no?
No, it was just an oversight on the poster's part. The assembly code was
not identical. There was code after that part which initialized the memory
in the case with the () included, just as there should have been.

-Howard
Aug 18 '06 #31
Pete Becker wrote:
Frederick Gotham wrote:
Signed char may trap in C (it may also contain padding).

6.2.6.1/5:

Certain object representations need not represent a value of the
object type. If the stored value has such a representation and
is read by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. If such a representation is
produced by a side effect that modifies all or any part of the
object by an lvalue expression THAT DOES NOT HAVE CHARACTER
TYPE, the behavior is undefined. Such a representation is
called a trap representation. [emphasis added]

Reading and writing a value through any character type are both well
defined, i.e. they do not trap.
And that's an important feature, because it allows one to cast the
pointer to an object to a char type (unsigned ususally) and examine the
byte representation of that object without worrying about a trap.

Brian

Aug 18 '06 #32
In article <11**********************@h48g2000cwc.googlegroups .com>,
<to***********@yahoo.comwrote:
>
Is this related to the C++ feature where;

int x;

int y = int();

y is guaranteed to be initialized?
Related may not be the right word, but yes.
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in alpha!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 18 '06 #33
In article <_w*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:
>Greg Comeau posted:
>It probably didn't actually do the zero new in the latter case
and happened to return a pointer to a block that was already zero'd.

The assembly code was identical though -- so "new" must zero its memory by
default on that system... no?
Then the compiler is one or more of: broken, not conformant,
not in strict mode, has an extension, or, the 0'ing code was
unobvious.
--
Greg Comeau / 20 years of Comeauity! Intel Mac Port now in alpha!
Comeau C/C++ ONLINE == http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Aug 18 '06 #34
Default User posted:
>Reading and writing a value through any character type are both well
defined, i.e. they do not trap.

And that's an important feature, because it allows one to cast the
pointer to an object to a char type (unsigned ususally) and examine the
byte representation of that object without worrying about a trap.

Yes, I do so frequently -- but I always use the "unsigned" flavour.

In C++, neither signed char nor unsigned char may contain padding. As plain
char is congruent to one of these types, plain char may not contain padding
either.

In C, unsigned char may not contain padding, but signed char may. As plain
char is congruent to one of these types, plain char may contain padding.

When talking about C, it's best to indicate whether you're talking about
C89 or C99. C89 is the more dominant of the two.

Signed char can trap in C89.

As for signed char trapping in C++, it's hard to get a definitive answer --
just look how conclusive the responses are to this thread:

http://groups.google.ie/group/comp.s...9edfa2eed6267b
c2/47ccdf97703d87c1?lnk=st&q=&rnum=1&hl=en#47ccdf9770 3d87c1

--

Frederick Gotham
Aug 18 '06 #35

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.