The code:
#include <vector>
int main()
{
std::vector<int> v1 = {12, 34};
std::vector<int> v2 = {56, 78};
//Doesn't work.
v1.push_back(v2[0]);
//Works.
int i = v2[0];
v1.push_back(i);
return 0;
}
For some reason, the first push_back doesn't work, while the second does. Eclipse gives for that line the error:
Invalid arguments ' Candidates are: void push_back(const int &) void push_back(int &&) '
Could someone explain what is happening there? Thanks!
EDIT:
The code actually compiles fine. For some reason, Eclipse doesn't agree that this is valid code.
If I compile the code with g++ 4.7.3 with
g++ test.cpp --std=c++0x
It compiles correctly and if I try to print v1[2];, I get the correct result.
std::cout << v1[2]; // 56
The Eclipse code analyzer tool (CODAN) may just not be right in this situation.
Rely on the output of a C++ (in this case C++11 compatible) compiler.
Related
I have this piece of code summing std::valarray<int>'s:
#include <iostream>
#include <valarray>
#include <vector>
int main()
{
std::vector<std::valarray<int>> vectorOfValarrays{{1, 1}, {2, 2}, {3, 3}};
std::valarray<int> sumOfValarrays(2);
for (const auto& i : vectorOfValarrays)
sumOfValarrays = sumOfValarrays + i;
std::cout << sumOfValarrays[0] << ' ' << sumOfValarrays[1];
}
Compiling with x86-64 gcc 12.2 using -O0 and -O1, it prints the expect result:
6 6
But when compiling with -O2 and -O3, it prints:
3 3
What could be the reason for this? Is my code undefined behaviour or is this a gcc bug?
I'm pretty sure that this is a gcc bug. Clang gives the correct behaviour for all optimization levels (-O0, -O1, -02, -O3). I also have a look at std::valarray constructors, operator + and operator = and it seems like my code doesn't any undefined behaviour.
I found this bug report on gcc Bugzilla, and the problem seems like gcc has the wrong implementation for copying std::valarray, so in the question the line sumOfValarrays = sumOfValarrays + i; makes gcc tripped up.
After updating to GCC 12.1, I got a array subscript ‘__m256d_u[0]’ is partly outside array bounds error (or rather warning with -Werror) in my project, so I tried isolating the problem.
Here's an MWE, which I also put on godbolt (vector type is __m512d_u instead, but otherwise it's the same error):
#include <Eigen/Dense>
#include <iostream>
using Eigen::Array;
Array<double, 3, 2> foo(){
Array<double, 2, 2> a;
a.setRandom();
Array<double, 3, 2> b;
b.col(0).tail(2) = a.col(1);
// b.col(0).template tail<2>() = a.col(1);
return b;
}
int main(){
std::cout << foo() << '\n';
return 0;
}
Relevant compile options are -Wall -Wextra -Werror -O3 -march=native, and the error message notes note: at offset [16, 24] into object ‘a’ of size 32.
The error does not occur under the following circumstances:
on GCC 11.3 or older,
when removing -march=native
when using -O1 or below
when replacing the line b.col(0).tail(2) = a.col(1); with b.col(0).template tail<2>() = a.col(1);
So it looks like GCC sees the 3x2 array and the 2x2 array, and doesn't realise that only two entries are accessed each.
My question now is: Who should this be reported to? GCC, Eigen? Or is it a user bug?
Bonus points for telling me what the 24 in the error note (offset [16, 24]) is. The 16 is the start, is the 24 the read size?
EDIT: Example can be further simplified by using Array3d and Array2d, see here.
This needs little explanation, but I'm expecting to get an ambiguity error from the following C++ code, however my compiler gives me different results that are apparently not part of the standard.
Environment:
Windows
Clang++ version 12.0.0
Clang++ target = x86_64-pc-windows-msvc
#include <iostream>
void print(int x) {
std::cout << "INT\n";
}
void print(double d) {
std::cout << "DOUBLE\n";
}
int main() {
print(5l); // 5l is type long, should cause ambiguity
}
output:
INT
Any idea why this is happening? My compiler is choosing the function taking an int for some reason instead of issuing an ambiguity error since it shouldn't be able to resolve the function call. Is there some conversion logic that I missed? Do I need to turn up some 'error levels' or something along those lines? Or is this a bug in the compiler? Thanks.
Turned out I had to add -fno-ms-compatibility to my clang compiler flags to switch off MSVC compatibility.
I have the following SSCCE:
#include <iostream>
#include <string>
void foo(const std::string &a) {
std::cout << a << std::endl;
}
template <typename... Args>
void bar(Args &&... args) {
[&]() {
[&]() {
foo(args...);
}();
}();
}
int main() {
const std::string x("Hello World!");
bar(x);
}
Under clang++ (3.9.1) this compiles and emits "Hello World". Gcc 6.3 fails with a segmentation fault under -O3.
I can fix the problem by explicitly passing the pointer and the pack by reference, replacing [&]() with [&args...](). However, up to now, I thought that [&] would do the same as listing all arguments one by one.
So what is going wrong here?
P.S:
This is not limited to -O3. -O0 does not segfault but does not return the expected result ("Hello World!"):
[:~/tmp] $ g++-6 -std=c++1z param.cpp && ./a.out
[:~/tmp] $
P.P.S: Further reduced SSCCE. Now I don't even get a diagnostic with -Wall -Wextra anymore.
I strongly suspect a g++ bug.
Here are some notes:
replacing std::string with any elementary type, e.g., int still does not work
clang and VC++ will work just as intended
not passing parameter pack by reference causes an internal compiler error with g++ 7.0.1 with the following output:
internal compiler error: in make_decl_rtl, at varasm.c:1304
...
Please
submit a full bug report, with preprocessed source if appropriate.
Please include the complete backtrace with any bug report. See
http://gcc.gnu.org/bugs.html for instructions.
I have the following SSCCE:
#include <iostream>
#include <string>
void foo(const std::string &a) {
std::cout << a << std::endl;
}
template <typename... Args>
void bar(Args &&... args) {
[&]() {
[&]() {
foo(args...);
}();
}();
}
int main() {
const std::string x("Hello World!");
bar(x);
}
Under clang++ (3.9.1) this compiles and emits "Hello World". Gcc 6.3 fails with a segmentation fault under -O3.
I can fix the problem by explicitly passing the pointer and the pack by reference, replacing [&]() with [&args...](). However, up to now, I thought that [&] would do the same as listing all arguments one by one.
So what is going wrong here?
P.S:
This is not limited to -O3. -O0 does not segfault but does not return the expected result ("Hello World!"):
[:~/tmp] $ g++-6 -std=c++1z param.cpp && ./a.out
[:~/tmp] $
P.P.S: Further reduced SSCCE. Now I don't even get a diagnostic with -Wall -Wextra anymore.
I strongly suspect a g++ bug.
Here are some notes:
replacing std::string with any elementary type, e.g., int still does not work
clang and VC++ will work just as intended
not passing parameter pack by reference causes an internal compiler error with g++ 7.0.1 with the following output:
internal compiler error: in make_decl_rtl, at varasm.c:1304
...
Please
submit a full bug report, with preprocessed source if appropriate.
Please include the complete backtrace with any bug report. See
http://gcc.gnu.org/bugs.html for instructions.