GCC optimalizations ignore for loop condition - c++

so I wrote this code:
#include <iostream>
constexpr
int fibonacci (int n) {
int a = 0;
int b = 1;
for(auto i = 0; i < n; i++) {
b += a;
a = b - a;
}
return b;
}
template<int N, int (T)(int)>
struct array {
using type = decltype(T(0));
constexpr array() : arr() {
for (auto i = 0; i < N; ++i) {
arr[i] = T(i);
}
}
const type &operator[](int i) const { return arr[i]; }
private:
type arr[N];
};
int main() {
constexpr auto x = array<10, fibonacci>();
for (int i = 0; i < 11; i++) {
std::cout << i << " " << x[i] << std::endl;
}
}
And without optimizations it works as expected, prints 11 values with last one being random value. But as soon I move to -O2 I get randomly long list of numbers finished with crash and segmentation fault.
I checked this result on godbolt.org (https://godbolt.org/z/4MqjbPbxE) and it seems that it is not a problem in, for example, clang.
My question is, is this a bug in gcc? Why would optimizations remove/not check condition in for loop?

You are invoking undefined behavior by using out-of-range x[i].
Allocate one more to avoid out-of-range access.
In other words,
constexpr auto x = array<10, fibonacci>();
should be
constexpr auto x = array<11, fibonacci>();
Defining constant to avoid typo is better:
int main() {
constexpr int num = 11;
constexpr auto x = array<num, fibonacci>();
for (int i = 0; i < num; i++) {
std::cout << i << " " << x[i] << std::endl;
}
}

Fix checking index.
for (int i = 0; i < 10; i++) {

Related

Function not returning any value in following code

#include <bits/stdc++.h>
using namespace std;
int myfunc(int n, int m, int k, int arr[], int arr1[]) {
int x = 0, y = 0;
for (int i = 0; i < n; ++i) {
if (arr[i] > k) {
x += 1;
}
}
for (int i = 0; i < m; ++i) {
if (arr1[i] > k) {
y += 1;
}
}
return max(x, y); // why is this not working?
}
int main() {
int n, m, k;
int arr[n];
int arr1[m];
cin >> n >> m >> k;
cout << "first: \n";
for (int i = 0; i < n; ++i) {
cin >> arr[i];
}
cout << "2nd arr\n";
for (int i = 0; i < m; ++i) {
cin >> arr1[i];
}
myfunc(n, m, k, arr, arr1);
return 0;
}
In this code function is not returning any value but when I use cout<<max(x,y) instead of return max(x,y), it's working fine. Can anyone explain me why is this happening?
Your confusion seems to be arising from a misunderstanding of what it means to return a value from a function versus printing the value inside the function. Consider the following function that prints the right answer:
void f()
{
std::cout << 42;
}
Fine, this works and can be called like f();, and it prints the values.
On the other hand, if the function were to return a value, like this:
int f()
{
return 42;
}
then simply calling the function f(); is not going to do anything because you are not using the returned value. Instead, you need to do something like:
std::cout << f();
From C++17, you can use an attribute for a function that returns a value, indicating that the returned value is meant to be used, and that not using it is a mistake:
[[nodiscard]] int f()
{
return 42;
}
This has the nice property that a call like f(); will throw a warning, and the only way to avoid the warning is to actually use the returned value.

Why is it necessary to define an array as a global variable when returning an array in a function? [duplicate]

This question already has answers here:
How to return an array from a function?
(5 answers)
Closed 2 years ago.
Why is it necessary to define an array as a global variable when returning an array in a function?
int v[10] = { 1,2,3,44,55,66,77,8,9,1 };
auto fun()->int(*)[10]
{
//int v[10] = { 1,2,3,44,55,66,77,8,9,1 };/
return &v;
}
int main()
{
auto t = fun();
for (int i = 0; i <= 10; i++)
cout << (*t)[i] << endl;
}
First, your code is C++ and not C, so I'll respond accordingly.
You can return a C++-style std::array, which is an object rather than a C-style array and thus can be returned by value:
#include <iostream>
#include <array>
int v[10] = { 1,2,3,44,55,66,77,8,9,1 };
auto fun()->std::array<int, 10>
{
std::array<int, 10> v;
v[0] = 5;
v[1] = 32;
//int v[10] = { 1,2,3,44,55,66,77,8,9,1 };/
return v;
}
int main()
{
auto v = fun();
for(size_t i = 0; i < 10; i++) {
std::cout << v[i] << std::endl;
}
}
You could have dynamically allocated the array instead, in which case you return a pointer and the caller is responsible for freeing it:
auto fun2()->int*
{
auto v = new int[10];
v[0] = 1;
// assign other elements
return v;
}
int main()
{
auto t2 = fun2();
for (int i = 0; i < 10; i++)
std::cout << t2[i] << std::endl;
delete[] t2;
}
You're simply not allowed to allocate the array on the stack and then return it, because the lifetime of stack variables is over as soon as your function returns. With that said, this example is valid because the array is allocated in main's stack frame and outlives all of its uses:
void fillIn(int* ar, size_t len) {
for (size_t i = 0; i < len; i++) {
ar[i] = 32; // or whatever logic you want
}
}
int main()
{
int x[10];
fillIn(x, 10);
for (int i = 0; i < 10; i++) {
std::cout << x[i] << std::endl;
}
}

declaring a function with arrays

First of all, im a c++ noob! Ok with that being said, i need to declare a function that initializes a grid. The function takes an array of int as the input and needs to return an array of int. I have:
array<int> InitializeGrid (array<int>)
{
const int NB_ROWS = 10;
const int NB_COLUMN = 10;
const int WATER = 0;
int grid[NB_ROWS][NB_COLONN];
for (int i = 0; i < NB_ROWS; i++)
{
for (int j = 0; j < NB_COLONN; j++)
{
grid[i][j] = WATER;
cout << grid[i][j] << " ";
}
cout << endl;
}
return ??
}
You don't need to return anything if you pass the array by reference:
#include <array>
#include <iostream>
static const int NB_ROWS = 10;
static const int NB_COLUMN = 10;
static const int WATER = 0;
void InitializeGrid (std::array<std::array<int, NB_COLUMN>, NB_ROWS> &grid)
{
for (auto &row : grid)
{
for (auto &col : row)
{
col = WATER;
std::cout << col << " ";
}
std::cout << '\n';
}
}
int main()
{
std::array<std::array<int, NB_COLUMN>, NB_ROWS> grid;
InitializeGrid(grid);
}
btw, if your WATER is 0 it is sufficive to write
std::array<std::array<int, NB_COLUMN>, NB_ROWS> grid{};
to initialize all elements to zero.

Removing cout statement causing value change of a variable

In the following code, when I'm removing cout statement (line after //******)then it is causing a change in the value of "i".
I used TDM-GCC 4.9.2 32 bit release and TDM-GCC 5.1.0 compilers.
I ran this code on codechef and there it runs fine and cout statement is not affecting the value of "i".
#include<iostream>
using namespace std;
int subset(int [], int);
int main()
{
int size,i,ans;
cout<<"size of array : ";
cin>>size;
int arr[size];
for(i = 0 ; i<size;i++)
{
cin>>arr[i];
}
ans = subset(arr,size);
cout<<"ans = "<<ans;
return 0;
}
int subset(int arr[], int size)
{
int i,j, tsum=0, completed=0;
for(i = 0 ;i<size;i++)
tsum = tsum + arr[i];
int carr[tsum+1],temp;
for(i=0;i<size;i++)
{
temp = arr[i];
carr[temp] = 1;
for(j=i+1;j<size;j++)
{
temp = temp + arr[j];
carr[temp] = 1;
}
}
for(i=1;i<=tsum;i++)
{
if(carr[i]!=1)
{
//************************************
cout<<"i : "<<i<<endl;
break;
}
}
return i;
}
Sample input :
size of array : 3
1
2
5
sample output without cout statement :
ans = 6
sample output having cout statement :
i : 4
ans = 4
Actual answere is 4 for the input.
The main problem seems to be that carr is uninitialized.
It is declared as
int carr[tsum+1]
with no initializer.
Later on some elements are set, but always to 1:
carr[temp] = 1;
In the last loop carr is examined:
if(carr[i]!=1)
This condition makes no sense. Either carr[i] has been set, then it is guaranteed to be 1, or it is uninitialized, in which case this comparison has undefined behavior.
Note that variable-length arrays are not standard C++.
To solve the problems as stated by Some Programmer Dude and melpomene, i.e. Variable-length arrays are not standard C++ and carr is uninitialized. Use c++ vectors and initialize them correctly. That would look something like this:
#include <iostream>
#include <vector>
using namespace std;
int subset(const std::vector<int>, const int);
int main()
{
int size, i, ans;
cout << "size of array : ";
cin >> size;
std::vector<int> arr(size);
for (i = 0; i < size; i++)
{
cin >> arr[i];
}
ans = subset(arr, size);
cout << "ans = " << ans;
return 0;
}
int subset(const std::vector<int> arr, const int size)
{
int i, j, tsum = 0, completed = 0;
for (i = 0; i < size; i++)
tsum = tsum + arr[i];
std::vector<int> carr(tsum + 1, 0);
int temp;
for (i = 0; i < size; i++)
{
temp = arr[i];
carr[temp] = 1;
for (j = i + 1; j < size; j++)
{
temp = temp + arr[j];
carr[temp] = 1;
}
}
for (i = 1; i <= tsum; i++)
{
if (carr[i] != 1)
{
//************************************
cout << "i : " << i << endl;
break;
}
}
return i;
}

is the operator overloading slow down performance?

im trying to make memory pool class and have to overload operator[], but theres a huge(2x) slow down:
T(overloaded) = 76.4043 ns
T(not-ovld) = 28.6016 ns
is it normal or im doing something wrong? thanks for help :)
compiler vc++2013
optimization disabled/full - same thing
class(main.cpp):
template<class T>
class pool{
public:
T *cell;
size_t size = 0;
public:
pool(const size_t n ){
size = n;
cell = new T[size];
}
T& operator [](const size_t i) { return cell[i]; }
T operator [](const size_t i)const { return cell[i]; }
};
main(main.cpp):
template<class T>
T F( T x){
return x/2 % 100;
}
#define test_count 10000000
int main()
{
pool<unsigned int> P(test_count);
unsigned int sum = 0;
resettimer();
// test 1
for (int i = 0; i < test_count; i++)
P[i] = F(i);
for (int i = 0; i < test_count; i++)
sum = sum + P[i];
cout << sum << endl;
//
printtimer();
sum = 0;
resettimer();
// test2
for (int i = 0; i < test_count; i++)
P.cell[i] = F(i);
for (int i = 0; i < test_count; i++)
sum = sum + P.cell[i];
cout << sum << endl;
//
printtimer();
int q;
cin >> q;
return 0;
}
Problem was with Debug build, in Release build (optimization n stuff) all works like it should. Hehe stupid mistake but taught me something :)
Conclusion - dont measure performence in debug mode ;)