There is such code:
#include <iostream>
int main()
{
int size;
std::cin >> size;
size = size + 1;
int tab3[size];
tab3[0] = 5;
std::cout << tab3[0] << " " << sizeof(tab3) << std::endl;
return 0;
}
The result is:
$ g++ prog.cpp -o prog -Wall -W
$ ./prog
5
5 24
Why does this code even compile? Shouldn't be length of array a constant variable?
I used g++ version 4.4.5.
Variable-length arrays in C++ are available as an extension in GCC. Compiling with all warnings should have alerted you to that fact (include -pedantic).
It is a C99 feature, not a part of C++. They are commonly refered to as VLAs(Variable Length Arrays.
If you run g++ with -pedantic it will be rejected.
See GCC docs for more info.
See also: VLAs are evil.
GCC provide's VLA's or variable length arrays. A better practice is to create a pointer and use the new keyword to allocate space. VLA's are not available in MSVC, so the second option is better for cross platform code
Related
Following is the code:
int add = foo;
vector signed int v_add;
v_add[0] = add;
The error is: error: invalid types 'vector int[int]' for array subscript
Problem stays when I try add = v_add[0];
Please explain the cause of this problem. I am using gnu version 3.3.2
Works for me:
$ cat vec.cpp
#include <altivec.h>
void foo () {
int add = 1;
vector signed int v_add;
v_add[0] = add;
}
$ g++ -c vec.cpp
$ g++ --version
g++ (GCC) 8.4.1 20200928 (Red Hat 8.4.1-1)
You can't treat AltiVec types like vector signed int as if they are arrays. Use e.g. the vec_ld intrinsic to load values from an array to an AltiVec vector.
I'm learning now C++ I'm reading the book Effective C++ (Scott Meyers).
In the book, there is an item about const variables, and I try to work with them.
I notice something very interesting that I what to know if it bug in C++:
(I'm working with C++98 standard)
void Test(const int i)
{
int arr[i] = {0};
for (int j = 0; i > j; ++j)
{
arr[j] = i;
}
}
This function will compile and work exactly as I want (create int array on the stack with the size of 'i'. When I remove the 'const' from 'i' it won't compile.
I try this on gcc and clang.
Edit:
link to Compiler Explorer
To catch this kind of mistake in the future the compiler flag you want for both g++ and clang++ is -pedantic. And always remember to specify your language standard or you don't know what you'll get.
$ g++ -std=c++98 -pedantic c++-vla.cpp -o c++-vla
c++-vla.cpp: In function ‘void f(size_t)’:
c++-vla.cpp:3:30: warning: ISO C++ forbids variable length array ‘g’ [-Wvla]
3 | void f(const size_t x) { int g[x]; }
| ^
$ clang++ -std=c++98 -pedantic c++-vla.cpp -o c++-vla
c++-vla.cpp:3:31: warning: variable length arrays are a C99 feature [-Wvla-extension]
void f(const size_t x) { int g[x]; }
^
1 warning generated.
First of all, const in your function signature is ignored by the compiler. So the following two are equivalent:
Test(const int i) {}
Test(int i) {}
Secondly, this isn't valid C++ regardless of whether it compiles or not:
int arr[i] = {0};
It isn't valid because i is not a compile time constant i.e., the value of i has to be known at the time of compilation.
Try on Compiler Explorer
See that example:
//test.cpp
#include <iostream>
void test(unsigned int i, int j) {
std::cout << i << " " << j << std::endl;
}
int main() {
test(-1, -1);
int x = -1;
test(x,x);
return 0;
}
with:
$ g++ -Wall -Wextra -Wpedantic test.cpp:
4294967295 -1
4294967295 -1
Why does gcc let that slip? And is there an option to detect such an implicit conversion?
Cheers
This has been answered before. One of the reasons is because C allowed it, and c++ was meant to be backwards compatible. Some compilers will warn, though I tested on gcc 5.2 and it does not have an option to turn that warning on.
See: Why does C++ allows implicit conversion from int to unsigned int?
#
Just found from one of the other answers that you need to add the -Wsign-conversion flag. Seems -Wall should do that but doesn't.
Yup, I found it. Misassumed that (-Wall -Wextra -W -Wpedantic -Wconversion) would cover it all. But in
https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
the missing flag is: -Wsign-conversion
I'd like to assign a specific value to a variable when my code is compiling (for C and C++):
For example having :
//test.c
int main()
{
int x = MYTRICK ; (edit: changed __MYTRICK__ to MYTRICK to follow advices in comment)
printf ("%d\n", x);
return 0;
}
beeing able to do something like:
gcc -XXX MYTRICK=44 test.c -o test
and having as a result :
$./test
44
Use -D option:
gcc -DMYTRICK=44 test.c -o test
And use MYTRICK macro in your program and not __MYTRICK__. Names beginning with __ are reserved by the implementation.
So I was talking to my friend, helping her with a piece of code, and I always thought that arrays needed to be compile-time constants, as they are on the stack. But she said that her friend did this using this code:
#include <iostream.h>
#include <stdlib.h>
int main()
{
int value = ' ' ;
int sum = 0;
int count = 0;
cout<<"Please enter the total number of employees" <<endl;;
cin>> value;
int numbers[value];
cout<<"Now enter the employees corresponding salaries" <<endl;;
for (int k = 0; k < value; k++)
{
cin >> numbers[k];
}
}
They are using Dev-C++.
Is this code suppose to work? I assume not.
Variable-length arrays are an extension in gcc and g++ ... so this won't work in every compiler.
For more information on gcc's support for variable length arrays, you can see the documentation here.
I believe that variable length arrays are officially unsupported in C++ but certain compilers and/or language extensions implement them.
If you want a variable length array I recommend using std::vector.
You can view its reference here:
http://www.cplusplus.com/reference/stl/vector/
#include <iostream.h>
^ is not a standard header. It used to be there in pre-standard times, i.e. before 1998. It's not there in e.g. modern Visual C++.
cin>> value;
int numbers[value];
Variable Length Arrays, or VLAs, were introduced in C99, a year after C++ was standardized. So they were not part of original standard C++, and happily they were not adopted in C++11 either. Instead of such beast, use e.g. std::vector from the vector header, or some other standard library container.
g++ supports variable length arrays as a language extension. You'd better turn off such extension. E.g.,
d:\dev\test> g++ foo.cpp
d:\dev\test> g++ -pedantic -std=c++0x -Wall -O foo.cpp
foo.cpp: In function 'int main()':
foo.cpp:11: warning: ISO C++ forbids variable length array 'numbers'
foo.cpp:7: warning: unused variable 'sum'
foo.cpp:8: warning: unused variable 'count'
d:\dev\test> _
I tried compiling it using GCC 4.6, and found that the code you've posted compiled successfully. I also tried running it and found that it worked, but I don't think the code is very good.