Impossible C++ array indexing [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C arrays why is this true? a[5] == 5[a]
Accessing arrays by index[array] in C and C++
I just found what seems to be a bug in my code, but not only it compiles, it also works as expected initially...
Consider the following code snipet:
#include <string>
#include <iostream>
using namespace std;
class WeirdTest
{
public:
int value;
string text;
WeirdTest() : value(0),
text("")
{}
virtual ~WeirdTest()
{}
void doWeirdTest()
{
value = 5;
string name[] =
{
"Zero",
"One",
"Two",
"Three",
"Four",
"Five"
};
text = value[name];
cout << "text: " << text << endl;
}
};
int main(int argc, char** argv)
{
WeirdTest test;
test.doWeirdTest();
return 0;
}
Instead of having text=value[name]; it should have been text=name[value]; but the compiler does not complain, and the resulting binary code is the exact same whether the "bug" is here or not.
I'm compiling using g++ 4.6.3, and if someone know what is going on here I would be very grateful. Could it be something in the standard that I missed ? Automatic bug-fix in C++0x maybe ? ;)
Thanks a lot,
Cheers !

Yes, that's a curious "feature". Actually what happens is that the compiler translates the a[i] into *(a + i), so array index and array address are actually interchangeable.
Note, it's valid only if operator [] isn't overloaded.

Related

Why can't I dereference and cout this string in C++ [duplicate]

This question already has answers here:
no operator "<<" matches these operands [duplicate]
(3 answers)
Closed 6 years ago.
I have this function:
void strPointerTest(const string* const pStr)
{
cout << pStr;
}
If I call it like this:
string animals[] = {"cat", "dog"};
strPointerTest(animals);
it returns the address of the first element. So I was expecting if I dereference it, I'd get the 1st element of the array but doing so like this:
void strPointerTest(const string* const pStr)
{
cout << *(pStr);
}
It won't even let me compile. I tried this using int instead of string and it works. Is there something special with strings? How would I retrieve the elements of the string array in this function?
EDIT:
Here's a complete example and it won't compile on my end:
#include <iostream>
void strPointerTest(const std::string* const pStr);
void intPointerTest(const int* const pInt);
int main()
{
std::string animals[] = { "cat", "dog" };
strPointerTest(animals);
int numbers[] = { 9, 4 };
intPointerTest(numbers);
}
void strPointerTest(const std::string* const pStr)
{
std::cout << *(pStr);
}
void intPointerTest(const int* const pInt)
{
std::cout << *(pInt);
}
I don't know why the downvote. I'm asking for help because it won't compile on my end. If it works on your end doesn't mean it also works on mine. I'm asking for help because I don't know what's happening.
The compilation error is:
No operator "<<" matches these operands - operand types are: std::ostream << const std::string
On some compilers <iostream>happens to also include the <string> header. On other compilers, specifically the Microsoft compiler, it apparently does not. And the I/O operators for strings are declared in the <string> header.
It is your responsibility to include all the needed headers, even if the code sometimes happen to work anyway.
So the fix is to just add
#include <string>
at the top of the file.

why are these NOT overloading functions? [duplicate]

This question already has answers here:
Passing an array as an argument to a function in C
(11 answers)
Closed 7 years ago.
I read here:
C: differences between char pointer and array
that char pointers and char arrays are not the same. Therefore, I would expect these to be overloading functions:
#include <iostream>
using namespace std;
int function1(char* c)
{
cout << "received a pointer" << endl;
return 1;
}
int function1(char c[])
{
cout << "received an array" << endl;
return 1;
}
int main()
{
char a = 'a';
char* pa = &a;
char arr[1] = { 'b' };
function1(arr);
}
Yet upon building I get the error C2084: function 'int function1(char *)' already has a body. Why does the compiler seem to consider a char pointer to be the same as a char array?
Because when you pass an array into a function, it magically becomes a pointer.
Your two functions, then, are the same.
The following are literally* identical:
void foo(int arr[42]);
void foo(int arr[]);
void foo(int* arr);
(* not lexically, of course :P)
This historical C oddity is the major reason lots of people mistakenly think that "arrays are pointers". They're not: this is just a bit of an edge case that causes confusion.

Why doesn't while (*s++=*t++); work for me?

I came across this function on a blog and I found it really cool. I understand how it works conceptually since C++ was my first language.
However, when I tried actually writing it out in a program of mine, it doesn't seem to work. I've googled all over but I've only found explanations as to how it works so I've been really stumped.
Instead of copying the NULL char[5] (which should evaluate to false, copy nothing and break the loop), it gives two compilation errors, saying that "I can't increment value of type char[6]" (out-of-bounds error for both arrays).
Why doesn't my loop break at char[5]?
I'm guessing it's something to do with the subtleties of char and string, I tried initialising strings instead with cstring included, that didn't work either, the similar error of "cannot increment type string" shows up.
#include <iostream>
using namespace std;
int main () {
char s[] = "hello";
char t[] = "house";
while (*s++ = *t++);
cout << s;
return 0;
}
You can't increment an array. What would that even mean?
Try this:
#include <iostream>
using namespace std;
int main ()
{
char s[] = "hello";
char t[] = "house";
char *ss = s;
char *tt = t;
while (*ss++ = *tt++);
cout << s << endl;
}
The line " while (*ss++ = *tt++) " is always going to be true, because = is the assignment operator. You probably want " while (*ss++ == *tt"")", which compares equality.

Initialization of const array in C++ [duplicate]

This question already has answers here:
initialize a const array in a class initializer in C++
(10 answers)
Closed 9 years ago.
I need to initialize a const int array in a class constructor via initialization list in C++.
I know that there is an easy solution of this problem based on using
extended initialization list.
Still, I want to avoid using -std=c++11 or -std=gnu++11.
Obviously, I know from the beginning that its size is 4 and the
content is {1, 2, 3, 4}.
The only way I can conceive doing this while staying out of the C++11 initializer list realm is to bury it in a struct wrapper and value-initialize it in your construct-initializer list:
#include <iostream>
using namespace std;
struct ArrayWrap
{
int content[4];
int& operator [](size_t n) { return content[n]; }
int operator [](size_t n) const { return content[n]; }
};
static const ArrayWrap content = { {1,2,3,4} };
struct MyObj
{
const ArrayWrap arrwrap;
MyObj() : arrwrap(content) {}
};
int main(int argc, char *argv[])
{
MyObj obj;
for (int i=0;i<4;++i)
cout << obj.arrwrap[i] << ' ';
cout << endl;
return EXIT_SUCCESS;
}
Output
1 2 3 4
It is common in C to bury fixed arrays in structures when returning them from functions by value, and in this case I'm simply exploiting the default copy-ctor of the wrapper struct as-generated by the C++ compiler.
Probably not the ideal solution for what you want, but it does work, and compiles under C++98.
Well, if you're banning C++11 solutions from the candidate set, then you simply cannot do this.

C++ passing/accessing matrix by pointers [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
2D arrays with C++
Hi, I'm trying to copy a pointer to a matrix that i'm passing in to a function in C++. here's what my code is trying to express
#include <iostream>
using namespace std;
void func( char** p )
{
char** copy = p;
cout << **copy;
}
int main()
{
char x[5][5];
x[0][0] = 'H';
func( (char**) &x);
return 0;
}
However, this gives me a Seg Fault. Would someone please explain (preferrably in some detail) what underlying mechanism i'm missing out on? (and the fix for it)
Thanks much in advance :)
A pointer to an array of 5 arrays of 5 char (char x[5][5]) has the type "pointer to array of 5 arrays of 5 chars", that is char(*p)[5][5]. The type char** has nothing to do with this.
#include <iostream>
using namespace std;
void func( char (*p)[5][5] )
{
char (*copy)[5][5] = p;
cout << (*copy)[0][0];
}
int main()
{
char x[5][5];
x[0][0] = 'H';
func(&x);
return 0;
}
Of course there are many other ways to pass a 2D array by reference or pointer, as already mentioned in comments. The most in-detail reference is probably StackOverflow's own C++ FAQ, How do I use arrays in C++?
char** is a pointer to a pointer (or an array of pointers). &x is not one of those - it's a pointer to a two-dimensional array of chars, which can be implicitly converted to a pointer to a single char (char *). The compiler probably gave you an error, at which point you put in the cast, but the compiler was trying to tell you something important.
Try this instead of using a char**:
#include <iostream>
using namespace std;
void func( char* &p )
{
char* copy = p;
cout << copy[0];
}
int main()
{
char x[5][5];
x[0][0] = 'H';
func(&x[0]);
return 0;
}