I have a bit of code copied from an unknown source:
int Len=0;
printf("Please input the length of vector");
scanf("%d",&Len);
float x[Len],y[Len],sig[Len];
Now normally I believe that arrays cannot be initialized during runtime with a variable. However, this does allegedly compile. Problem is that again I do not know the compiler. Is there a C variant where this is legal? The compiler I am using, IAR C, does not like it.
I am also seeing arrays indexed from 1 rather than 0, which suggests this is translated from something like Pascal originally. Any opinions?
Now normally I believe that arrays cannot be initialized during runtime with a variable.
That has been true before C99 standard. It is also illegal in C++ (although some compilers, such as gcc, offer this as an extension).
Is there a C variant where this is legal?
Any C99 compiler will do.
I am also seeing arrays indexed from 1 rather than 0
This is OK as well, as long as you are fine allocating an extra element, and not using element at index zero.
Note: since accessing an element past the end of an array is undefined behavior, an invalid program may appear to work and produce the desired result in your test runs. If you suspect that some array indexes may be off by one, consider running your program under a memory profiler, such as valgrind, to see if the program has hidden errors related to invalid memory access.
This was a feature introduced in C99 and are called VLAs(Variable Length Arrays). These arrays are also indexed starting from 0 not 1 and ending at length-1(Len-1 in your case) just like a normal array.
In C99 this is valid and called a VLA-Array.
This is called a Variable Length Array (VLA) and is a C99 feature.
If your compiler does not recognise it on it's own then try switching C standards
Try:
--std=c99
-std=c99
--std=gnu99
-std=gnu99
The manual page of your compiler will be able to tell you the exact flag.
Related
i want to know c compiler behavior with strings
i am using windows 7 code block with GCC
int main()
{
"1145"; "ho";
printf("hello");
}
so i want to know unused string consume memory space or not
First you need to understand l(eft)-values and r(ight)-values.
l-values actually are memory locations, where objects are stored.
r-values are data, that supposed to be stored in some place in memory (in l-value).
So your construct "1145"; "ho";
makes two r-values that are not assigned anywhere. You can even make this (perfectly valid) code:
int main(){
;;
printf("hello");
}
This is allowed because ; is null statement operator. You will, not once, see expressions like
while(*ptr++); // ajusts pointer until contents of the pointer become 0
where while is actually executing every iteration ;
I'm 99% sure that this strings didn't use any space at all, because GCC without any option recognized unused statement and didn't generate any code for this line.
Compiling the code shown and assuming you enabled enough warnings you can expect the following being issued by the compiler:
warning: statement with no effect [-Wunused-value]
So the compiler seems to have noticed that those strings are "unused". Knowing this and being told to "optimise" the compilation those strings might very well be removed and would not use any memory at all.
If the compiler has been told to not optimise the strings will be part of the program and use at least sizeof "1145" + sizeof "ho" bytes.
Further readings:
To enable GCC's warnings use its -Wxyz options.
To steer optimisation with GCC use its -O option.
i am solving a problem. In my code i have two arrays
array[];
array2[];
i am inputing 2 numbers through scanf , and i want the size of arrays to be the count of number 1 and 2 e.g
int x;
int y;
scanf(" %d %d\n",&x,&y);
int indexX[x*y];
int indexY[x*y];
This does not work.
Being new to C im quite lost how to implement it , is the only way dynamicly allocate memory? If no , how can i achieve wanted result ? Or how could i dynamicly alocate the memory for it?
my code throws error
warning: ISO C++ forbids variable length array ‘indexX’ [-Wvla]
warning: ISO C++ forbids variable length array ‘indexY’ [-Wvla]
According to your error messages, you compile with a C++ compiler. Do not! C is not C++ and C++ is not C with classes. They are different languages. As the messages state, C++ does not provide VLAs (see below).
Use a standard-compliant C compiler, or at least a C99 compiler. Variable length arrays (VLAs) were added with the C99 release of the standard as a mandatory feature. C11 relaxed this by making it optional, but most (if not all) compilers which support C99 also implement it in C11 mode.
before defining the array, you should verify scanf really set these two variables by checking the result of scanf. Otherwise you use uninitialised variables, which is undefined behaviour and may (likely - will) result in strange behaviour - at best.
Additinally you can also initialise the variables before scanf to 1 (a VLA of size 0 is also undefined behaviour). This way you can check later and are still safe with the VLA definition.
Warning: Most, if not all modern implementations place VLAs on the stack. The size of the stack is normally limited to some 100 bytes (embedded systems) up to some MiB (standard OS like Windows, OS-X, Linux). There is no check if the VLA fits onto the stack, so you should not allocate too large arrays. If you are not sure, better use dynamically allocated memory (malloc& friends).
I know that I'm not supposed to do this in C90, and it's a rather basic stuff.
char name[strlen(s)];
ArrayLength.c:11: warning: ISO C90 forbids variable length array ‘name’
Did they want me to specifically use malloc? I'm just curios here about the logic behind it.
It's forbidden because C90 doesn't support variable-length arrays (VLAs). It's really as simple as that.
Your options are:
Declare a fixed-length array that can cope with the maximum string length you want to work with.
Dynamically-allocate the array (using malloc).
Work with a compiler that offers VLAs a non-standard language extension, e.g. GCC. (I don't recommend this, because it means you'll end up writing non-portable code.)
Use C99 instead, where VLAs are supported. Note that VLAs are allocated on the stack, which can cause all sorts of issues if you run out of stack space (unlike with malloc, there's no concept of being able to check that the allocation was successful).
[Note: If you're allocating an array in order to make a copy of s, you'll need to use strlen(s)+1 as the size (remember the null terminator).]
It's not that "they" don't want you to do it, it's simply not part of the language (or rather, wasn't prior to 1999). The standard workaround is to use malloc or alloca. (alloca is essentially identical to variable length array allocation, but is not a standard function, so it may not be available on all systems of interest. Also, some people have strong objections to it's use, but they tend to object strong to variable-length arrays for the same reasons.)
This warning points to the usage of a GNU gcc extension is a serious portablity problem.
The code is illegal, because the value of strlen(s) is not known at compile time. GNU gcc provides an extension for automatic arrays that allocate based on run time values; but relying on these makes the code out of compliance with the standard.
If the value of strlen(s) isn't known until run-time then one can bring the code into compliance by either converting to performing the allocation/deallocation explicitly on conventions arrays, or by using STL containers.(e.g. std::vector).
It's a matter of the language having restrictions for the presumed convenience of the
compiler and its intended runtime environment.
In C, I have read that half-initialized arrays will be filled with zeros for the rest of the elements (irrespective of integer or char arrays).
E.g.:
int arr[10] = {3};
arr[4] will be 0 if initialized and a junk value if not initialized.
My question is, will the above work for all C compilers (or) this appending of zeros might occur or not occur depending on the compiler option? I am working in Code composer studio (TI's IDE). I want to ensure that this will work for all cases and all compilers.
The behaviour is specified by the C Standard. But if you are worried about the behaviour of your specific compiler, why not write a test?
This is according to the C standard, and any compiler following the C standard must do this. However, not all compilers are 100% standard compliant, and you'll have to check if yours does this or not, if you're unsure.
Variables, located in data segment (global and unit scope), are automatically initialised to all zeros.
Stack variables (function and block scope) are filled with garbage unless explicitly initialised, even partially initialised. In case of partial initialisation, reminder is zeroed.
That's by the C standard and all compilers must adhere to it.
This should work irrespective of which compiler you are using.
If you want to be sure that your code will work with all compilers you should initialize all your array elements just like it:
int arr[10] = {3,0,0,0,0,0,0,0,0,0};
If the number of elements of your array is too high (100 or 10000) the best solution becomes to initialize it dynamicaly at the runtime.
It is dependent on the design of the compiler. Normally compilers support it and some may support via some flags during compilation or other options. Some may not support it. It is better to check with the concerned compiler support regd the compatibility with C standard. I think Code Composer Studio IDE(TI DSP processors) support group might give you the exact answer.
Karthik Balaguru
The language spec specifies default behavior, however not all compilers implement the defined behavior. A good example of this is that Visual Studio 2008 is the first version of the Microsoft C/C++ compiler that will call the default constructor on uninitialized elements in an array which has been the defined behavior of array initialization since at least the C++ 98 spec.
If you are worried about how your code will behave running on multiple compilers it is better to be safe than sorry and explicitly initialize all values.
A colleague of mine recently got bitten badly by writing out of bounds to a static array on the stack (he added an element to it without increasing the array size). Shouldn't the compiler catch this kind of error? The following code compiles cleanly with gcc, even with the -Wall -Wextra options, and yet it is clearly erroneous:
int main(void)
{
int a[10];
a[13] = 3; // oops, overwrote the return address
return 0;
}
I'm positive that this is undefined behavior, although I can't find an excerpt from the C99 standard saying so at the moment. But in the simplest case, where the size of an array is known as compile time and the indices are known at compile time, shouldn't the compiler emit a warning at the very least?
GCC does warn about this. But you need to do two things:
Enable optimization. Without at least -O2, GCC is not doing enough analysis to know what a is, and that you ran off the edge.
Change your example so that a[] is actually used, otherwise GCC generates a no-op program and has completely discarded your assignment.
.
$ cat foo.c
int main(void)
{
int a[10];
a[13] = 3; // oops, overwrote the return address
return a[1];
}
$ gcc -Wall -Wextra -O2 -c foo.c
foo.c: In function ‘main’:
foo.c:4: warning: array subscript is above array bounds
BTW: If you returned a[13] in your test program, that wouldn't work either, as GCC optimizes out the array again.
Have you tried -fmudflap with GCC? These are runtime checks but are useful, as most often you have got to do with runtime calculated indices anyway. Instead of silently continue to work, it will notify you about those bugs.
-fmudflap -fmudflapth -fmudflapir
For front-ends that support it (C and C++), instrument all risky
pointer/array dereferencing
operations, some standard
library string/heap functions, and some other associated
constructs with range/validity tests.
Modules so instrumented
should be immune to buffer overflows, invalid heap use, and some
other classes of C/C++ programming
errors. The instrumen‐
tation relies on a separate runtime library (libmudflap), which
will be linked into a program if
-fmudflap is given at link
time. Run-time behavior of the instrumented program is controlled
by the MUDFLAP_OPTIONS environment
variable. See "env
MUDFLAP_OPTIONS=-help a.out" for its options.
Use -fmudflapth instead of -fmudflap to compile and to link if your program is multi-threaded. Use
-fmudflapir, in addition
to -fmudflap or -fmudflapth, if instrumentation should ignore pointer reads. This produces
less instrumentation (and there‐
fore faster execution) and still provides some protection against
outright memory corrupting writes, but
allows erroneously
read data to propagate within a program.
Here is what mudflap gives me for your example:
[js#HOST2 cpp]$ gcc -fstack-protector-all -fmudflap -lmudflap mudf.c
[js#HOST2 cpp]$ ./a.out
*******
mudflap violation 1 (check/write): time=1229801723.191441 ptr=0xbfdd9c04 size=56
pc=0xb7fb126d location=`mudf.c:4:3 (main)'
/usr/lib/libmudflap.so.0(__mf_check+0x3d) [0xb7fb126d]
./a.out(main+0xb9) [0x804887d]
/usr/lib/libmudflap.so.0(__wrap_main+0x4f) [0xb7fb0a5f]
Nearby object 1: checked region begins 0B into and ends 16B after
mudflap object 0x8509cd8: name=`mudf.c:3:7 (main) a'
bounds=[0xbfdd9c04,0xbfdd9c2b] size=40 area=stack check=0r/3w liveness=3
alloc time=1229801723.191433 pc=0xb7fb09fd
number of nearby objects: 1
[js#HOST2 cpp]$
It has a bunch of options. For example it can fork off a gdb process upon violations, can show you where your program leaked (using -print-leaks) or detect uninitialized variable reads. Use MUDFLAP_OPTIONS=-help ./a.out to get a list of options. Since mudflap only outputs addresses and not filenames and lines of the source, i wrote a little gawk script:
/^ / {
file = gensub(/([^(]*).*/, "\\1", 1);
addr = gensub(/.*\[([x[:xdigit:]]*)\]$/, "\\1", 1);
if(file && addr) {
cmd = "addr2line -e " file " " addr
cmd | getline laddr
print $0 " (" laddr ")"
close (cmd)
next;
}
}
1 # print all other lines
Pipe the output of mudflap into it, and it will display the sourcefile and line of each backtrace entry.
Also -fstack-protector[-all] :
-fstack-protector
Emit extra code to check for buffer overflows, such as stack smashing attacks. This is done by adding a guard variable to functions with vulnerable objects. This includes functions that call alloca, and functions with buffers larger than 8 bytes. The guards are initialized when a function is entered and then checked when the function exits. If a guard check fails, an error message is printed and the program exits.
-fstack-protector-all
Like -fstack-protector except that all functions are protected.
You're right, the behavior is undefined. C99 pointers must point within or just one element beyond declared or heap-allocated data structures.
I've never been able to figure out how the gcc people decide when to warn. I was shocked to learn that -Wall by itself will not warn of uninitialized variables; at minimum you need -O, and even then the warning is sometimes omitted.
I conjecture that because unbounded arrays are so common in C, the compiler probably doesn't have a way in its expression trees to represent an array that has a size known at compile time. So although the information is present at the declaration, I conjecture that at the use it is already lost.
I second the recommendation of valgrind. If you are programming in C, you should run valgrind on every program, all the time until you can no longer take the performance hit.
It's not a static array.
Undefined behavior or not, it's writing to an address 13 integers from the beginning of the array. What's there is your responsibility. There are several C techniques that intentionally misallocate arrays for reasonable reasons. And this situation is not unusual in incomplete compilation units.
Depending on your flag settings, there are a number of features of this program that would be flagged, such as the fact that the array is never used. And the compiler might just as easily optimize it out of existence and not tell you - a tree falling in the forest.
It's the C way. It's your array, your memory, do what you want with it. :)
(There are any number of lint tools for helping you find this sort of thing; and you should use them liberally. They don't all work through the compiler though; Compiling and linking are often tedious enough as it is.)
The reason C doesn't do it is that C doesn't have the information. A statement like
int a[10];
does two things: it allocates sizeof(int)*10 bytes of space (plus, potentially, a little dead space for alignment), and it puts an entry in the symbol table that reads, conceptually,
a : address of a[0]
or in C terms
a : &a[0]
and that's all. In fact, in C you can interchange *(a+i) with a[i] in (almost*) all cases with no effect BY DEFINITION. So your question is equivalent to asking "why can I add any integer to this (address) value?"
* Pop quiz: what is the one case in this this isn't true?
The C philosophy is that the programmer is always right. So it will silently allow you to access whatever memory address you give there, assuming that you always know what you are doing and will not bother you with a warning.
I believe that some compilers do in certain cases. For example, if my memory serves me correctly, newer Microsoft compilers have a "Buffer Security Check" option which will detect trivial cases of buffer overruns.
Why don't all compilers do this? Either (as previously mentioned) the internal representation used by the compiler doesn't lend itself to this type of static analysis or it just isn't high enough of the writers priority list. Which to be honest, is a shame either way.
shouldn't the compiler emit a warning at the very least?
No; C compilers generally do not preform array bounds checks. The obvious negative effect of this is, as you mention, an error with undefined behavior, which can be very difficult to find.
The positive side of this is a possible small performance advantage in certain cases.
There are some extension in gcc for that (from compiler side)
http://www.doc.ic.ac.uk/~awl03/projects/miro/
on the other hand splint, rat and quite a few other static code analysis tools would have
found that.
You also can use valgrind on your code and see the output.
http://valgrind.org/
another widely used library seems to be libefence
It's simply a design decision ones made. Which now leads to this things.
Regards
Friedrich
-fbounds-checking option is available with gcc.
worth going thru this article
http://www.doc.ic.ac.uk/~phjk/BoundsChecking.html
'le dorfier' has given apt answer to your question though, its your program and it is the way C behaves.