Consider the following snippet:
#include <iostream>
using namespace std;
int a[10][2];
int b[10][2];
int main(){
//intended
cout << a[0][0] - b[0][0] << endl;
//left out dimension by mistake
cout << a[0] - b[0] << endl;
}
Obviously (or maybe not per comments) the second case is valid pointer arithmetic in both C and C++ but in the code base I am working with it is generally a semantic mistake; a dimension has usually been left out in a nested for loop. Is there any -W flag or static analysis tool that can detect this?
You could use std::array which will not allow that:
using d1=std::array<int, 2>;
using d2=std::array<d1, 10>;
d2 a;
d2 b;
std::cout << a[0][0] - b[0][0] << endl; // works as expected
std::cout << a[0] - b[0] << endl; // will not compile
Another option is to use a specialized multidimensional array library with appropriate operator error handling, such as boost::multi_array (http://www.boost.org/doc/libs/1_55_0/libs/multi_array/doc/user.html). This is usually a better idea then using nested containers or POD arrays.
If this is only concern for << operator as in example, overload of operator << for int* might help - you can overload operator to generate compile-time error.
Related
I see some people tend to initialize a vector with an empty {}, and I wonder whether it is different from directly initialize with the default constructor?
for example:
#include <vector>
#include <iostream>
using namespace std;
int main()
{
vector<int> vec;
vector<int> vec2 {};
cout << sizeof(vec) << " " << sizeof(vec2) << endl; // 24 24
cout << vec.size() << " " << vec2.size() << endl; // 0 0
}
and I check its assembly code, and it shows that initializing a vector with an empty {} generate more code(https://godbolt.org/z/2BAWU_).
Assembly code screen shot here
I am quite new to C++ language, and I would be grateful if someone could help me out.
Using braces is value initialization. Not using them is default initialization. As somebody alluded to in the comments, they should generate the exact same code when optimizations are turned on for vector. There's a notable difference with built-in types like pointers and int; there default initialization does nothing, while value initialization sets them to nullptr and zero, respectively.
Here is my problem:
int addsomeStuff(std::ostream &cout, int b) {
cout << b;
return 2;
}
int main() {
int a = 1;
cout << a << addsomeStuff(cout, 3) << endl;
return 0;
}
Output: 312
Can Someone explain me the Output, i would expect the output more like 132
why is the compiler runs first the Function before making the operator.
How i run into this issue:
I have a container class which can hold data inside an bytearray.
Somehow the 'container.WriteConvert(..);' get inserted into bytearray before the integer called 'a'. Does anyone have an explaintation for that.
I could make the WriteConvert static or add an extra Line which would fix this problem, instead of returning an Container& but i am kinda intrested whats the reason the Compiler puts this in this order.
int a = 2;
Container container;
container << a << container.WriteConvert("TestString");
int b = 0;
container >> b;
cout << b;
// The ouput of 'b' is some stupid Data which is caused by WriteConvert.
The Reason i didnt wrote this WriteConvert static or outside of the Container class has some reason. I have also ReadConvert which i dont want to have multiline. If someone has another idea i am open for other solutions, without increasing line amount.
int b = 0;
string output
container >> b >> container.ReadConvert(output);
cout << b;
Pre C++17, the order of evaluation of the chained operator arguments' was unspecified. That means the execution could've first evaluated addsomeStuff(cout, 3) call (thus printing 3 first) and then proceed to print a and the returned value of addsomeStuff(cout, 3).
With C++17, the order of evaluation is well defined - left to right. That means that if your compiler correctly implements the C++17 standard, the only possible output is 132.
If you are stuck with a pre C++17 standard, you would need to first evaluate all the arguments and then use them in chained operator call or don't use chained operator calls:
int main() {
int a = 1;
cout << a;
cout << addsomeStuff(cout, 3) << endl;
return 0;
}
The former approach may alter the behaviour, but will be well-defined.
I have some issues getting my head around the idea of pointers. I know what they do in theory, but i have a problem understanding what they can actually be capable of. The basic exercises that i have seen are a bit vague in my opinion because they can be done without the actual subject. For example swapping two number, either by reference or by address.
#include <iostream>
using namespace std;
int main()
{
int a = 45, b = 35;
cout << "Before Swap\n";
cout << "a = " << a << " b = " << b << "\n";
int z = a;
a = b;
b = z;
cout << "After Swap with pass by reference\n";
cout << "a = " << a << " b = " << b << "\n";
}
//copied an example i saw online with pointers and modified it to get the
same result without needing them
One example on when using pointers could be better (assuming this is some sort of school context) would be if you want to make a function to swap the numbers instead of rewriting your code a lot.
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
return
}
If you tried using integers in the function instead of pointers, it'd swap the values locally, and not swap the variables in a greater context. What you could do to achieve the same results is use references instead (ie int &a, int &b), so you don't really need to use pointers, and in this example they aren't particularly useful.
Pragmatically, std::swap()is much more useful in modern c++, but the example above might be why the online tutorial uses pointers.
Pointers can be useful in other contexts, but I don't know if that's within the scope of your question, just perhaps what the tutorial was trying to achieve by using pointers.
Use the std::swap() method for swaping.
It is more efficient.
For your understanding if we write a function which swaps two values
so we have to pass the values by reference and not by value.
same is
the case with pointers.some time we need to swap value by pointers.
So if we pass values to this function from the main it will swap it.
void swap(int&,int&);
But here it won't work if we pass values to this function from the main.
void swap(int,int);
Could someone explain to me why the offsetof function does not work on std::vectors as shown below:
#include <windows.h>
#include <iostream>
#include <vector>
using namespace std;
struct FooStruct {
double x;
double y[10];
std::vector<double> z;
};
int main() {
cout << offsetof(FooStruct, x) << endl;
cout << offsetof(FooStruct, y[2]) << endl;
cout << offsetof(FooStruct, z[2]) << endl;
system("Pause");
}
Calling offsetof(FooStruct, z[2]) produces the following compiling error:
cannot apply 'offsetof' when 'operator[]' is overloaded
offsetof(FooStruct, z[2]) makes no sense. The elements of z are not contained within a FooStruct, they're accessed via the std::vector, which has at its core a pointer to some other allocation on the heap within which z[2] can be found.
In any case, the error (which seems confusing I understand) is probably popping up because std::vector overloads operator[], not because your class FooStruct overloads operator[] (which, assuming we see the whole definition, it doesn't).
If you want to find the offset of z[2] in relation to z[0], you could just compute the difference between &z[0] and &z[2] like this: std::cout << (&z[2] - &z[0]) << '\n';
Because offsetof isn't a function but a macro, and only works on POD types, or standard layout class in C++11. It's only there for backward compatibility with C.
The reason the compiler refuses to allow you to use the subscription operator, all issues aside, is because the macro is evaluated at compile time, but the overloaded operator might do some work at runtime to calculate the result.
Sorry beginner here. I'm trying to get the string size from the cin function, then use that to declare array size. But it's saying:
line 17: request for member 'size' in 'x', which is non-class type 'std::string long int'.
It works fine without the array though.
#include <iostream>
#include <string>
using namespace std;
int main()
{
int y;
string x[y];
cout << "Enter sequence" << endl;
cin >> x[y];
y = x.size;
for (int i = 0; i > y; i++)
cout x[i];
cout << "The size of the sequence is " << x.size() << " characters." << endl;
}
First, of all declaring an array as you do is not allowed. Let's take a look at these two lines of code
int y;
string x[y];
In the second line of code, what is the value of y? It could be anything. Certainly the compiler doesn't know, and the array size must be determined at compile-time.
There are two solutions to your problem:
Use pointers and dynamically allocate an array.
Use std::vector and let the standard library take care of the dynamic allocation.
IMO, both are tools which you should have in your programmer tool belt, so you should learn how to do both. You should also learn the advantages and disadvantages of either approach so that you can choose the correct one to solve a problem.
Finally, the error message that you get means that an array does not have a member called size(). If you fix this using solution 1. above, you will need to keep track of the size yourself.