Ye Olde General C++ Discussion/Advice Thread

It does exactly follow, since as I said, the spec says that addition of a pointer and an integral type is commutative. A compiler than doesn't do this, is not standard compliant.
Yes it does say this but it's also assumed that each would have its place of use. A compiler encountering a none pointer followed by a pointer as a subscript to it and flagging it an error would still be standard compliant as there's nothing stating non-standard types should be allowed.
 
Yes it does say this but it's also assumed that each would have its place of use. A compiler encountering a none pointer followed by a pointer as a subscript to it and flagging it an error would still be standard compliant as there's nothing stating non-standard types should be allowed.

No. If arbitrary ordering was not allowed then a would not be equivalent to *(a+b), which is what the standard defines it to be equivalent to.
 
No. If arbitrary ordering was not allowed then a would not be equivalent to *(a+b), which is what the standard defines it to be equivalent to.

You don't get it. It's not about the ordering. It's about the data types. The standard says a should be calculated as *(a+b). That says nothing about allowing arbitrary ordering of data types. The situation gets even worse when using multidimensional arrays with multiplication where such arbitrary ordering would lead to incorrect and different results.
 
You don't get it. It's not about the ordering. It's about the data types. The standard says a should be calculated as *(a+b). That says nothing about allowing arbitrary ordering of data types. The situation gets even worse when using multidimensional arrays with multiplication where such arbitrary ordering would lead to incorrect and different results.


The fact that the standard says that the add is commutative between pointer and integral types, means that arbitrary ordering between these types must be supported. I've already stated this twice. Is this really so complicated?

The generalization works fine too, as one would expect from induction: for 2D array m, you can index it like: 1[2[m]] to get the same as m[2][1]. [1][2]m is not ok, since subscripts are evaluated left to right, and dereferencing the sum of integers doesn't make sense.
 
Last edited:
The fact that the standard says that the add is commutative between pointer and integral types, means that arbitrary ordering between these types must be supported. I've already stated this twice. Is this really so complicated?
The standard you quoted doesn't say anything about it being commutative so it is a matter of your interpretation.

The generalization works fine too, as one would expect from induction: for 2D array m, you can index it like: 1[2[m]] to get the same as m[2][1]. [1][2]m is not ok, since subscripts are evaluated left to right, and dereferencing the sum of integers doesn't make sense.
So let's do the calculation. If m is an array of chars of [3][3] then m[2][1] would be
m + 2 x 3 + 1 = m + 7

1[2[m]] would be
1 + 2[m] = 1 + 2 + m = 3 + m

Clearly not the same thing because arrays are more than just addition but also the size of data types and dimensions. This is assuming it works as expected. In reality 2[m] would be evaluated first and return what's stored at the result of 2+m and not 2+m itself. It's therefor the equivalent of 1[*(2+m)] and not 1[(2+m)].

The same would be true of writing m[2][1] as 2[m][1] which your interpretation of the standard would allow. This would result in
2 + m x 3 + 1 = 3 + m x 3
instead of
m + 2 x 3 + 1 = m + 6 + 1 = m + 7

Clearly from that it can be seen that a = *(a+b) doesn't mean the inverse of *(a+b) = b[a] is also true. You are relying on a compiler quirk here so the inverse of what you say is actually true. It's the compilers that don't check for type safety that are non compliant while those that do are complying with the standard.
 
The standard you quoted doesn't say anything about it being commutative so it is a matter of your interpretation.

You probably want to look up what "commutative" means, sunshine. As I quoted earlier from section 5.3 of the standard:
cguy said:
... the expressions (P)+N (equivalently, N+(P)) ...

In case it got past you, P is a pointer and N is an integral type.

So let's do the calculation. If m is an array of chars of [3][3] then m[2][1] would be
m + 2 x 3 + 1 = m + 7

1[2[m]] would be
1 + 2[m] = 1 + 2 + m = 3 + m

Wow... No, there's this thing called "operator precedence".

1[2[m]] == 1[ *(2+m) ] == *( 1 + *(2+m) ) == *( 1 + (2x3 + (char*)m) ) == *(7 + (char*)m)

I can't believe you're just spewing out nonsense when you could just try it, and save yourself from looking like a complete idiot:

Code:
  char m[3][3] = { { 0, 1, 2 },
                   { 3, 4, 5 },
                   { 6, 7, 8 } };
  printf( "%u\n", m[2][1] );
  printf( "%u\n", 1[2[m]] );  
  printf( "%u\n", 2[m][1] );
  printf( "%u\n", 1[*(2+m)]);
Output is 7, 7, 7 and 7.

Clearly not the same thing because arrays are more than just addition but also the size of data types and dimensions. This is assuming it works as expected. In reality 2[m] would be evaluated first and return what's stored at the result of 2+m and not 2+m itself. It's therefor the equivalent of 1[*(2+m)] and not 1[(2+m)].

The only thing that's clear here is that you don't understand how multidimensional typing works. Pro tip: m isn't a (char*), the value 1[*(2+m)] is in fact exactly what I would expect and want (see code and output). Now you're arguing that it's doing the right thing ... "in reality".

The same would be true of writing m[2][1] as 2[m][1] which your interpretation of the standard would allow. This would result in
2 + m x 3 + 1 = 3 + m x 3
instead of
m + 2 x 3 + 1 = m + 6 + 1 = m + 7

What you think my interpretation would result in follows from your poor understanding of pointer arithmetic. Hint: The multiplier is applied to the value with the integral type, not the pointer, regardless of the order of addition. Once again, so easy to test... (see code above)

This is what my interpretation results in:
2[m][1] == *( *(2 + m) + 1 ) == *( (2x3 +(char*)m) + 1 ) == *( (char*)m + 2x3 + 1 ) = *( (char*)m + 7 )

Clearly from that it can be seen that a = *(a+b) doesn't mean the inverse of *(a+b) = b[a] is also true. You are relying on a compiler quirk here so the inverse of what you say is actually true. It's the compilers that don't check for type safety that are non compliant while those that do are complying with the standard.


So GCC, MSVC, ICC and CLANG, are all non-compliant then? Which ones are compliant pray tell?

I think that only one thing is actually clear...
 
Last edited:
Always fun to watch swa get owned.
 
Last edited:
You probably want to look up what "commutative" means, sunshine. As I quoted earlier from section 5.3 of the standard:


In case it got past you, P is a pointer and N is an integral type.
You should really take a look at what you are quoting. 5.3 is about expressions and addition. There (P)+N is equivalent to N+(P). It does not say that with subscripting E1[E2] is equivalent to E2[E1] and only that E1[E2] should be evaluated as *(E1+E2). It's your own conclusion from two different definitions that this is equivalent to *(E2+E1) and E2[E1] but it does not follow from the standard.

Wow... No, there's this thing called "operator precedence".

1[2[m]] == 1[ *(2+m) ] == *( 1 + *(2+m) ) == *( 1 + (2x3 + (char*)m) ) == *(7 + (char*)m)

I can't believe you're just spewing out nonsense when you could just try it, and save yourself from looking like a complete idiot:

Code:
  char m[3][3] = { { 0, 1, 2 },
                   { 3, 4, 5 },
                   { 6, 7, 8 } };
  printf( "%u\n", m[2][1] );
  printf( "%u\n", 1[2[m]] );  
  printf( "%u\n", 2[m][1] );
  printf( "%u\n", 1[*(2+m)]);
Output is 7, 7, 7 and 7.
Oh yes operator preference. The precedence is to calculate [] from left to right the same as () brackets. So in 1[2[m]] the precedence is to calculate what's contained in 1[] or 2[m] iow. As was pointed out 2[m] should result in the value stored at 2[m] if that is seen as a legal statement and not the pointer value of 2[m].

If it happens to work for you because of some quirk then fine. Just don't complain when none standard code doesn't compile on some compiler out there that you would like to believe is non-compliant.

Btw I've seen GCC complain about a lot less when mixing pointers with other types.

Always fun to watch swa get owned.
Always fun seeing people comment on a conversation they're not following and don't understand. ;)
 
You should really take a look at what you are quoting. 5.3 is about expressions and addition. There (P)+N is equivalent to N+(P). It does not say that with subscripting E1[E2] is equivalent to E2[E1] and only that E1[E2] should be evaluated as *(E1+E2). It's your own conclusion from two different definitions that this is equivalent to *(E2+E1) and E2[E1] but it does not follow from the standard.

Two chained definitions in the standard can be concatenated together to form a conclusion that follows from the standard. It's called transitivity. This is elementary logic, and your poor grasp of even this suggests that you may have some sort of learning disability (I'm not joking - do you?).

Oh yes operator preference. The precedence is to calculate [] from left to right the same as () brackets. So in 1[2[m]] the precedence is to calculate what's contained in 1[] or 2[m] iow. As was pointed out 2[m] should result in the value stored at 2[m] if that is seen as a legal statement and not the pointer value of 2[m].

The value returned by 2[m] is a pointer. Once again, you're just stating that expected behavior is expected, however, you don't believe that it's expected because you don't understand any of this.

If it happens to work for you because of some quirk then fine. Just don't complain when none standard code doesn't compile on some compiler out there that you would like to believe is non-compliant.

Btw I've seen GCC complain about a lot less when mixing pointers with other types.

Yes, it happens to work because of "some quirk" that has mysteriously affected every compiler on the planet, and is mandated in the standard, so I will take my chances. I expect that GCC complains a lot when (or if?) you code.

Always fun seeing people comment on a conversation they're not following and don't understand. ;)

You must get the giggles when you type then.
 
Two chained definitions in the standard can be concatenated together to form a conclusion that follows from the standard. It's called transitivity. This is elementary logic, and your poor grasp of even this suggests that you may have some sort of learning disability (I'm not joking - do you?).
You really are one for insults aren't you? Because that's the only thing you're really showing here. You are the one concatenating two definitions and not the standard. Transitivity is a mathematical concept. You are applying it to programming which has a lot more nuances. Tell me this: seeing as we've had an example previously of an expression that can be treated differently by compilers because the standard isn't clear on how to treat it, what makes you so sure this one would be treated the same across the board?

The moral here remains. You are using non-standard code which is not guaranteed to work according to any standard.
 
You really are one for insults aren't you? Because that's the only thing you're really showing here. You are the one concatenating two definitions and not the standard. Transitivity is a mathematical concept. You are applying it to programming which has a lot more nuances.

Transitivity is an essential logical concept. Without it, programming wouldn't exist, and language specifications (and grammar in general) would have no purpose. You are expected to apply it. Your complaint is essentially that commutative subscripting is not defined axiomatically, which simply tells anyone reading your posts that you don't "get" logic, and fundamentally do not understand the purpose of a grammar.

Tell me this: seeing as we've had an example previously of an expression that can be treated differently by compilers because the standard isn't clear on how to treat it, what makes you so sure this one would be treated the same across the board?

The standard is clear how to treat the previous example (multiple increments of the same variable between sequence points): it is specified as undefined behaviour (section 1.9, subsection 15). This one would be treated the same across compliant compilers because it is defined behaviour.

The moral here remains. You are using non-standard code which is not guaranteed to work according to any standard.

Well, I can't teach English to a tree, so whatever, dude.
 
Last edited:
It runs fine, but if you exit it by clicking enter (like I even suggest at the end in text, lol), it freezes the console. Exiting by clicking on the red x is fine.
...

2: What alternative is there to insert at the end of a program that's running in a console window to prevent the console window from closing automatically when the program finishes? (in my case I need to keep the console window open so that the user can view the lottery numbers that have been generated).

Thanks experts!

To pause a console app, just add
#include <conio.h>
and in the code before your final return
_getch();

Don't get too hung up on console apps, since in "the real world" these days everything with a frontend is usually GUI based.
 
To pause a console app, just add
#include <conio.h>
and in the code before your final return
_getch();

Don't get too hung up on console apps, since in "the real world" these days everything with a frontend is usually GUI based.

system("pause");
 
Okay guys, since everyone here just loves (*sarcasm*) these kinds of snippets I thought I'd give an easy yet interesting one. So try to predict the number of times that the message will be printed to the console.

Code:
#include <iostream>
using namespace std;

int main()
{
	int j=10; 
	int i=0; 

	while( ++i, --j) {
		cout << "I will not complain that realbigdreamer posted this (-_-)" << endl;
	}
}

If by some chance you don't know why the code behaves as it does, I will explain. Perhaps this one is too easy to predict... :)

Edit: I post this as it may actually not be obvious to someone learning C/C++.
 
Last edited:
Okay guys, since everyone here just loves (*sarcasm*) these kinds of snippets I thought I'd give an easy yet interesting one. So try to predict the number of times that the message will be printed to the console.

Code:
#include <iostream>
using namespace std;

int main()
{
	int j=10; 
	int i=0; 

	while( ++i, --j) {
		cout << "I will not complain that realbigdreamer posted this (-_-)" << endl;
	}
}

If by some chance you don't know why the code behaves as it does, I will explain. Perhaps this one is too easy to predict... :)

I predict 9, but I'm guessing. I didn't know that double statements were allowed there, but semantically I would expect them to be and'ed as the loop condition.
 
realbigdreamer: I see that you deleted your spoiler. :) Without giving it away, thanks - I learned something new.
 
cool example. At first you would think its an endless loop until you remember what true and false really is :)

Edit: I wonder if this is how NASA codes their launches ? :P
 
Last edited:
Top
Sign up to the MyBroadband newsletter
X