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? 10 7358
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
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
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?
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
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
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
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
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
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...
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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
by: Ying Yang |
last post by:
Hi,
whats the difference between:
char* a = new char;
char* b = new char;
char c ;
|
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...
|
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);
|
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 },
{...
|
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...
| |
by: thinktwice |
last post by:
char a = { 0 }
is it ok?
|
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...
|
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...
|
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...
|
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).
...
|
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...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
| |
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
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...
| |