473,487 Members | 2,601 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

char array initialization

During a review of one of my peer's code, I ran into a section of code
that was a bit suprising to me. Its got to do with initialization of
a variable-length array. I ran a small application to convince myself
whether it works or not, and it does work---however I couldn't explain
it to myself why, so I thought I'd ask here.

The sample code is below:

char test[] = "hello world\n"; // test string, but I could easily
have retrieved this string from a file or wherever
int len = strlen(test)+1;
// line below is the code of interest
char out[len];
strncpy(out, test, len);
printf("out: %s", out);

Note that 'out' is declared on the stack, yet 'len' is a variable
whose value is not known at compile time. Why would this work? I
would think the proper way of instantiating a char array with variable
length is using new, like "char *out = new char[len]", yet somehow the
above code works. Can someone explain why this works?

Nov 9 '07 #1
10 7356
Avalon1178 wrote:
During a review of one of my peer's code, I ran into a section of code
that was a bit suprising to me. Its got to do with initialization of
a variable-length array. I ran a small application to convince myself
whether it works or not, and it does work---however I couldn't explain
it to myself why, so I thought I'd ask here.

The sample code is below:

char test[] = "hello world\n"; // test string, but I could easily
have retrieved this string from a file or wherever
What do you mean, "retrieve from a file"? By including some text with
the string defined as a macro? It doesn't make this string "variable-
length".
int len = strlen(test)+1;
// line below is the code of interest
char out[len];
That's illegal in C++.
strncpy(out, test, len);
printf("out: %s", out);

Note that 'out' is declared on the stack, yet 'len' is a variable
whose value is not known at compile time. Why would this work?
Because the compiler with which it is compiled offered this syntax
as an extension, most likely.
I
would think the proper way of instantiating a char array with variable
length is using new, like "char *out = new char[len]", yet somehow the
above code works. Can someone explain why this works?
It's not legal C++. It works because the compiler wasn't compiling
C++, it was compiling "C++ with extensions".

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 9 '07 #2
On Nov 9, 1:32 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Avalon1178 wrote:
During a review of one of my peer's code, I ran into a section of code
that was a bit suprising to me. Its got to do with initialization of
a variable-length array. I ran a small application to convince myself
whether it works or not, and it does work---however I couldn't explain
it to myself why, so I thought I'd ask here.
The sample code is below:
char test[] = "hello world\n"; // test string, but I could easily
have retrieved this string from a file or wherever

What do you mean, "retrieve from a file"? By including some text with
the string defined as a macro? It doesn't make this string "variable-
length".
I'm just saying that 'test' could have been set or initialized
anywhere, and not necessary like the one I defined above (i.e. like
getline(), or snprintf, or whatever). I just did it for simple
demonstration.
>
int len = strlen(test)+1;
// line below is the code of interest
char out[len];

That's illegal in C++.
Yeah, that's what I thought too....
strncpy(out, test, len);
printf("out: %s", out);
Note that 'out' is declared on the stack, yet 'len' is a variable
whose value is not known at compile time. Why would this work?

Because the compiler with which it is compiled offered this syntax
as an extension, most likely.
I
would think the proper way of instantiating a char array with variable
length is using new, like "char *out = new char[len]", yet somehow the
above code works. Can someone explain why this works?

It's not legal C++. It works because the compiler wasn't compiling
C++, it was compiling "C++ with extensions".
Great! Thanks for the explanation.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Nov 9 '07 #3
Hmm.....so I gather it is compiler dependent. I compiled the code
using g++, and after doing g++ -v, here's the version it is running:

Reading specs from /usr/lib/gcc/i386-redhat-linux/3.4.6/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
disable-checking --with-system-zlib --enable-__cxa_atexit --disable-
libunwind-exceptions --enable-java-awt=gtk --host=i386-redhat-linux
Thread model: posix
gcc version 3.4.6 20060404 (Red Hat 3.4.6-3)

I'm still curious however....if say I am using this C++ with
extensions, how exactly is the compiler generating the assembly code
for 'char out[len]', since the compiled binary is working?

Nov 9 '07 #4
Avalon1178 wrote:
[..]
I'm still curious however....if say I am using this C++ with
extensions, how exactly is the compiler generating the assembly code
for 'char out[len]', since the compiled binary is working?
I am unclear what it is you'd like to know. If you want to see how
compilers generate assembly, you need to look into the compiler's
source code. Beyond that, why do you care how they do it? Magic,
would be my guess. Also, try asking in 'comp.compilers'.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 9 '07 #5
Avalon1178 wrote:
...
I'm still curious however....if say I am using this C++ with
extensions, how exactly is the compiler generating the assembly code
for 'char out[len]', since the compiled binary is working?
...
Have you ever heard of 'alloca' function? It allocates memory in the
stack, which then gets automatically deallocated when function exits.
(It is not a part of the standard C or C++ library).

That's pretty much how the compiler extension in question works. When
you write something like

char out[len];

where 'len' is a run-time value, the compiler actually generates
something like

char* out = alloca(len);

i.e. internally your 'out' is actually a pointer, not an array. That's it.

Of course, the full functionality of this extension is more complicated
than that. It has to provide proper C++ lifetime for the array and its
elements (which might end before the function returns), call the
constructors and destructors, make the 'sizeof' to see it as an array,
not a pointer, and so on. But the general memory management idea is not
much different from what is illustrated above.

--
Best regards,
Andrey Tarasevich
Nov 10 '07 #6
On Nov 9, 4:34 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
Avalon1178 wrote:
...
I'm still curious however....if say I am using this C++ with
extensions, how exactly is the compiler generating the assembly code
for 'char out[len]', since the compiled binary is working?
...

Have you ever heard of 'alloca' function? It allocates memory in the
stack, which then gets automatically deallocated when function exits.
(It is not a part of the standard C or C++ library).

That's pretty much how the compiler extension in question works. When
you write something like

char out[len];

where 'len' is a run-time value, the compiler actually generates
something like

char* out = alloca(len);

i.e. internally your 'out' is actually a pointer, not an array. That's it.

Of course, the full functionality of this extension is more complicated
than that. It has to provide proper C++ lifetime for the array and its
elements (which might end before the function returns), call the
constructors and destructors, make the 'sizeof' to see it as an array,
not a pointer, and so on. But the general memory management idea is not
much different from what is illustrated above.

--
Best regards,
Andrey Tarasevich
Andrey,

No, I've never heard of alloca() but thanks a lot for the
information! I really appreciate it.

Avalon1178

Nov 10 '07 #7
On Nov 9, 10:29 pm, Avalon1178 <Avalon1...@gmail.comwrote:
During a review of one of my peer's code, I ran into a section of code
that was a bit suprising to me. Its got to do with initialization of
a variable-length array. I ran a small application to convince myself
whether it works or not, and it does work---however I couldn't explain
it to myself why, so I thought I'd ask here.
The sample code is below:
char test[] = "hello world\n"; // test string, but I could easily
have retrieved this string from a file or wherever
int len = strlen(test)+1;
// line below is the code of interest
char out[len];
strncpy(out, test, len);
printf("out: %s", out);
Note that 'out' is declared on the stack, yet 'len' is a variable
whose value is not known at compile time. Why would this work?
It doesn't, at least not in C++. You may have activated some
local extension, or be compiling in C.
I would think the proper way of instantiating a char array
with variable length is using new, like "char *out = new
char[len]", yet somehow the above code works. Can someone
explain why this works?
It doesn't compiler with any of the compilers I use, at least
when I invoke them with the necessary options for them to
compile C++. None of the compilers are really C++ compilers if
just invoked without options. At the very least, for example,
g++ requires -std=c++98, VC++ requires things like /Ehs /GR
(from memory, I don't have a machine with the compiler handy at
the moment), and so on.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Nov 10 '07 #8
On Nov 9, 11:15 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Avalon1178 wrote:
[..]
I'm still curious however....if say I am using this C++ with
extensions, how exactly is the compiler generating the assembly code
for 'char out[len]', since the compiled binary is working?
I am unclear what it is you'd like to know. If you want to see how
compilers generate assembly, you need to look into the compiler's
source code. Beyond that, why do you care how they do it? Magic,
would be my guess. Also, try asking in 'comp.compilers'.
Just a guess, but it's probably doing the same thing the C
compiler does---his code was purely legal C.

There are two possible solutions: on many systems, it's possible
to just grab a hunk of the stack---on an Intel, "sub sp,N" will
do the trick. In cases where that doesn't work, there's nothing
to prevent the compiler from generating a call to malloc, with a
call to free on leaving the block.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Nov 10 '07 #9
On 10 nov, 05:51, Avalon1178 <Avalon1...@gmail.comwrote:
On Nov 9, 4:34 pm, Andrey Tarasevich <andreytarasev...@hotmail.com>
wrote:
Avalon1178 wrote:
...
I'm still curious however....if say I am using this C++ with
extensions, how exactly is the compiler generating the assembly code
for 'char out[len]', since the compiled binary is working?
...
Have you ever heard of 'alloca' function? It allocates memory in the
stack, which then gets automatically deallocated when function exits.
(It is not a part of the standard C or C++ library).
That's pretty much how the compiler extension in question works. When
you write something like
char out[len];
where 'len' is a run-time value, the compiler actually generates
something like
char* out = alloca(len);
i.e. internally your 'out' is actually a pointer, not an array. That's it.
Of course, the full functionality of this extension is more complicated
than that. It has to provide proper C++ lifetime for the array and its
elements (which might end before the function returns), call the
constructors and destructors, make the 'sizeof' to see it as an array,
not a pointer, and so on. But the general memory management idea is not
much different from what is illustrated above.
--
Best regards,
Andrey Tarasevich

Andrey,

No, I've never heard of alloca() but thanks a lot for the
information! I really appreciate it.
Hi Avalon1178,

When using gcc, you can use the -pedantic (use very carefully). It
will shows you whether your code is C++ compliant or not.

HTH
-Mahtieu
Ps: of course you also need to keep your -W -Wall falsg too...
Nov 10 '07 #10
Avalon1178 wrote:
char test[] = "hello world\n"; // test string, but I could easily
have retrieved this string from a file or wherever
int len = strlen(test)+1;
// line below is the code of interest
char out[len];
strncpy(out, test, len);
printf("out: %s", out);

Note that 'out' is declared on the stack, yet 'len' is a variable
whose value is not known at compile time. Why would this work? I
would think the proper way of instantiating a char array with variable
length is using new, like "char *out = new char[len]", yet somehow the
above code works. Can someone explain why this works?
Some compilers (I know of g++) extend the standard to allow
variable-length arrays (the reason being that this is allowed in C, and
it wouldn't make sense to disable it for C++). But the resulting code is
not portable, of course.

Bernd.
Nov 12 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

35
20914
by: Ying Yang | last post by:
Hi, whats the difference between: char* a = new char; char* b = new char; char c ;
20
7055
by: Petter Reinholdtsen | last post by:
Is the code fragment 'char a = ("a");' valid ANSI C? The problematic part is '("a")'. I am sure 'char a = "a";' is valid ANSI C, but I am more unsure if it is allowed to place () around the...
33
3114
by: baumann.Pan | last post by:
hi all, i want to get the address of buf, which defined as char buf = "abcde"; so can call strsep(address of buf, pointer to token);
14
2379
by: gustavo | last post by:
I was looking at the Sendmail's source code, and i've got confused about this kind of initialization: ------------------------ struct prival PrivacyValues = { { "public", PRIV_PUBLIC }, {...
10
5300
by: fei.liu | last post by:
Consider the following sample code char * ptr = "hello"; char carray = "hello"; int main(void){ } What does the standard have to say about the storage requirement about ptr and carray? Is...
15
26390
by: thinktwice | last post by:
char a = { 0 } is it ok?
21
2718
by: arnuld | last post by:
int main() { const char* arr = {"bjarne", "stroustrup", "c++"}; char* parr = &arr; } this gives an error: $ g++ test.cpp test.cpp: In function 'int main()': test.cpp:4: error: cannot...
14
71106
by: mdh | last post by:
And I thought I understood it, finally. Alas. given: char *s={"Jan","Feb","Mar","April"}; is it possible to have char *p point at s? *p = s...does not do it, as I expect. *p=s...I...
24
2151
by: DomoChan | last post by:
the code below will compile in visual c++ 2003, but im not sure its valid. unsigned char myString = ""; after this line executes, all the bytes within myString are indeed set to '0's' but is...
5
9837
by: codeGhost | last post by:
I've been trying to ignore this issue for a while now, but I've come to the point in my code where I can't do so anymore. (For those of you who are wondering, this is NOT a homework question). ...
0
7106
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
6967
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7181
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
6846
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
5442
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4565
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3071
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
600
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
267
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.