clang standard library bug or c++ undefined behavior? - c++

Does the following C++ program contain any undefined behavior?
int
main()
{
struct entry
{
uint32_t hash;
uint32_t idx;
};
entry arr[31] = {
{ 7978558, 0}, { 9241630, 1}, { 65706826, 2},
{ 639636154, 3}, {1033996244, 4}, {1225598536, 5},
{1231940272, 6}, {1252372402, 7}, {2019146042, 8},
{1520971906, 9}, {1532931792, 10}, {1818609302, 11},
{1971583702, 12}, {2116478830, 13}, { 883396844, 14},
{1942092984, 15}, {1274626222, 16}, { 333950222, 17},
{1265547464, 18}, { 965867746, 19}, {1471376532, 20},
{ 398997278, 21}, {1414926784, 22}, {1831587680, 23},
{ 813761492, 24}, { 138146428, 25}, { 337412092, 26},
{ 329155246, 27}, { 21320082, 28}, {1751867558, 29},
{1155173784, 30},
};
std::sort(std::begin(arr), std::end(arr),
[](entry a, entry b) { return a.hash <= b.hash; });
}
When I compile with gnu c++ compiler or any clang/llvm after 12.0.0, the program works fine. However, when I compiled it with clang version 12.0.0 (the default compiler shipped on my Mac laptop), it crashed inside of std::sort() as following:
$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.2)
Target: x86_64-apple-darwin21.3.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
$ g++ -g -std=c++11 bug.cc
$ ./a.out
Segmentation fault: 11
Also if I change it to use std::vector instead of fixed size array. The std::sort() will never return when compiled with clang 12.0.0

Yes, the comparator is not a strict weak ordering which violates the preconditions of std::sort, resulting in undefined behavior.
For two arguments a and b (possibly identical), a strict weak ordering comp should never evaluate both comp(a,b) and comp(b,a) to true. In other words, it should model the behavior of the built-in <, not <=.
So in your code it should be <, not <=, to make it a strict weak ordering.

Related

Different error on native compiler vs web compiler

I'm having a strange issue, and being new to c++ isn't helping. I wrote the following to make a simple 2D matrix:
#include <iostream>
#include <vector>
std::vector< std::vector<int> > grid(){
std::vector< std::vector<int> > vect;
vect = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
return vect;
}
When I run this on a site like cpp.sh, it works perfectly fine, but when I use g++ on my macbook, I get the following error:
username % g++ main.cpp
main.cpp:6:13: error: expected expression
vect = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
^
1 error generated.
I've updated my gcc, and I've run with both g++ and gcc – both have the same issue. I installed gcc with homebrew and i've just been running g++ main.cpp and then executing a.out.
Note: I'm on MacOS Monterey on M1
Thanks for the comments! For anyone else having similar issues:
On macOS Monterey gcc/g++ (by default) uses the 1998 version, where my code requires the 2011+ versions.
To compile with the newer version, #wlk showed that I could use clang++ -std=c++11 to specify the version.
By adding alias g++="clang++ -std=c++20" to my .zshrc file, I can run g++ with the 2020 version – without issue.

Initialising vector in C++

I'm initialising vector using the below method
vector<int> num1{1, 9, 3, 7, 0, 7, 7, 2, 1};
and it is throwing error as below,
Multiplication.cpp:29:18: error: expected ';' at end of declaration
vector<int> num1{1, 9, 3, 7, 0, 7, 7, 2, 1};
^
You haven't included the vector library,
just add
#include<vector>
at the top of your code
it is running check here
if you did that too, then too,
it is a compiler problem, try using a different complier or online complier like ideone

Does clang on Mac not support uniform initialization?

Is clang on Mac not support uniform initialization?
I tried compiling following code, But compiler raise a error.
#include <iostream>
#include <vector>
#include <string>
int main() {
std::vector<int> v = {3, 1, 9, 4};
std::cout << v[1] << std::endl;
}
Error:
vector.cpp:9:22: error: non-aggregate type 'std::vector<int>' cannot be initialized with an initializer list
std::vector<int> v = {3, 1, 9, 4};
^ ~~~~~~~~~~~~
1 error generated.
OS: macOS 10.12.4
compiler version:
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.5.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
I suspect you are not compiling the code as C++11/14 (-std=c++11 or -std=c++14)? If not; do that. Clang does support what you are trying to do.

Access auto declared array

auto messwerte2 = { 3.5, 7.3, 4.9, 8.3, 4.4, 5.3, 3.8, 7.5 };
Which possibilities exist to access a single value explicitly of this array-like looking structure which as I was informed is actually a std::initializer_list ?
Which possibilities exist to access a single value explicitly of this array?
It's not an array, but is deduced to a std::initializer_list<double> which can be accessed through an iterator or a range based loop:
#include <iostream>
auto messwerte2 = { 3.5, 7.3, 4.9, 8.3, 4.4, 5.3, 3.8, 7.5 };
int main() {
for(auto x : messwerte2) {
std::cout << x << std::endl;
}
}
Live Demo
To make it an array use an explicit array declaration:
double messwerte2[] = { 3.5, 7.3, 4.9, 8.3, 4.4, 5.3, 3.8, 7.5 };
auto messwerte2 = { 3.5, 7.3, 4.9, 8.3, 4.4, 5.3, 3.8, 7.5 };
doesn't declare an array. It declares a std::initializer_list<double>
To declare an array, use:
double messwerte2[] = { 3.5, 7.3, 4.9, 8.3, 4.4, 5.3, 3.8, 7.5 };
Then you can use the regular array indexing syntax.

can I use auto with g++ 4.4?

I can specify -std=c++0x for compilation with my g++ 4.4, and initializer lists are correct, I may use them (in c++98 I can't) but still get errors when try use auto keyword:
std::list< std::vector<int> > li2;
li2.push_back({1, 2, 3}); //push_back vector
li2.push_back({4, 2, 6}); //again, vector implicitly
for (auto& vv : li2) {
for (auto &i : v)
printf("element: %d\n", 8);
}
so I assume I can't use C++11 functionallities with g++4.4. I have 4.4 because of compatibility with CUDA.
This link shows you the different C++11 features supported by GCC. auto appeared in GCC 4.4.
Your real problem is probably that the ranged-based for loop appeared only in GCC 4.6.