Array of size defined by not constant variable - c++

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

Compilation error using AltiVec SIMD vector type in C++

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.

c++ variable size stack array in function that get const

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

Why do implicit conversions in function parameters of same size not throw a warning?

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

Assign a value to a variable at compilation time

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.

Arrays with a size determined at run time, is this valid in C++?

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.