Ye Olde General C++ Discussion/Advice Thread

No difference in speed. Only a poorly written compiler will return a result if you don't need one.

Usually true, however, for classes that have a non-trivial copy constructor and/or destructor or where the returned copy from the post-increment is actually used (e.g., c = "(a++).my_field;"), this can be very expensive in comparison to a pre-increment. Even if you don't need the result, if the compiler can't determine that the copy constructor or destructor doesn't have side effects, it can't optimize out the all the code (since it may, actually do more than just a POD copy or have a complex destruction).
 
Last edited:
Some fun with obfuscation: Without compiling, what does this output, and why does/doesn't it work?

Code:
#include <iostream>

int main() {
#include <iostream>

int main() {
  std::cout << &(6 + ((long)"Well, hello there." & 0x3))["Hello World"] << std::endl;  
}

No takers for this beauty? ;)
 
No takers for this beauty? ;)

When did this thread become about posting advanced riddles, with only the purpose of proving that you're smart enough to pose the riddle in the first place?

Come on guys, it's meant to be a helpful thread to people learning C++, so maybe rather post the answer and explain the humour behind it, so we can all get the joke :)
 
When did this thread become about posting advanced riddles, with only the purpose of proving that you're smart enough to pose the riddle in the first place?

Come on guys, it's meant to be a helpful thread to people learning C++, so maybe rather post the answer and explain the humour behind it, so we can all get the joke :)
Such examples also rely on strange quirks that are compiler specific. They'll also not compile on all compilers.
 
Such examples also rely on strange quirks that are compiler specific. They'll also not compile on all compilers.

There's nothing that relies on strange compiler quirks here. Actually, the entire point of this question is precisely that the bit that one would think is portable is not, and the bit that looks really strange is actually defined by the standard.
 
When did this thread become about posting advanced riddles, with only the purpose of proving that you're smart enough to pose the riddle in the first place?

Come on guys, it's meant to be a helpful thread to people learning C++, so maybe rather post the answer and explain the humour behind it, so we can all get the joke :)

It's not about proving intellect, or some "advanced riddle" (seriously??), it's a one line example that anyone can try out to see if results match expectation. Also, there is nothing about "General C++ discussion/advice" or your OP that implies that topics should be limited to beginner level or those just learning C++.

I posted this precisely because I was not aware of this myself until a few years back, and found the mechanism behind it enlightening. It highlights two interesting points about the language, and the hope is that you actually get a feeling for what some of the common constructs are doing under the hood and improve your understanding. It's not a joke, or humor, it's an example of some of the most uncommonly used, yet valid syntax I've seen - this is simply a learning exercise.

I will write up the interesting bits a bit later when I get home.
 
Last edited:
So, the bit that looks as though it should work, but isn't portable is:
Code:
((long)"Well, hello there." & 0x3)

The reason being that "long" does not necessarily map to the size of a pointer - it does on most variants of unix, but the standard only requires it to be at least 32-bits (and in MS C++, it remains so, even on 64-bit platforms). This is true even though it is and-ed with 0x3, which means that there is functionally no difference, regardless of it being 64-bit or 32-bit. This bit of code actually compiles on all platforms I've seen, and is a common source of compatibility errors from many experienced unix programmers. Incidentally, if "long" is replaced with an "int" on unix, it will require -fpermissive to compile at all (with a warning).

The really interesting bit, is the remaining code, which is now essentially:
Code:
&(X)["Hello world"]

Where X is an integer with the value 6 plus some integer between 0 and 3 inclusive. What is being taken advantage of over here is that (this is the bit I found surprising) in a piece of code like this, the following assignments are legal and equivalent:
Code:
int m[5];
...
int x = m[3];
// Is identical to:
int x = 3[m];

The reason for this is that m[3] = *(m+3) = *(3+m) = 3[m]. In the case of a string literal, which is just an array of characters, this means that 6["Hello World"], will give you 'W', and &6["Hello World"], will give you the pointer to 'W' in the string, so that cout would print out "World".

Because of the offset from the and-ed pointer, which incidentally, can be anything from 0-3 inclusive, since char alignment only has to align to its element size, the output will be 'World', 'orld', 'rld' or 'ld'.
 
Last edited:
Nice explanation, cguy, and at least now your riddle is accessible to people without years' experience (although the actual mechanics behind it are still unclear without that experience).

Here's a.more simple riddle: in the code I posted at the start (for my lottery generator), something is making the program crash when the enter is typed at the end (an action that is saved to a string before zeeo is.returned to signal the end of the program).

Is that's what's killing it - a string can't be empty? I only did that as a hack to stop the console window from closing at the end, after the program has finished running. Was there something else I should have done that actually works, without craahing?
 
Nice explanation, cguy, and at least now your riddle is accessible to people without years' experience (although the actual mechanics behind it are still unclear without that experience).

Here's a.more simple riddle: in the code I posted at the start (for my lottery generator), something is making the program crash when the enter is typed at the end (an action that is saved to a string before zeeo is.returned to signal the end of the program).

Is that's what's killing it - a string can't be empty? I only did that as a hack to stop the console window from closing at the end, after the program has finished running. Was there something else I should have done that actually works, without craahing?

Your code seems to work fine for me (Visual Studio Express 2010, 32-bit and 64-bit). It is fine for a string to be empty. My first thought would be that you corrupted the stack somehow, but I can't see where that may be happening.
 
Last edited:
Nice explanation, cguy, and at least now your riddle is accessible to people without years' experience (although the actual mechanics behind it are still unclear without that experience).

Here's a.more simple riddle: in the code I posted at the start (for my lottery generator), something is making the program crash when the enter is typed at the end (an action that is saved to a string before zeeo is.returned to signal the end of the program).

Is that's what's killing it - a string can't be empty? I only did that as a hack to stop the console window from closing at the end, after the program has finished running. Was there something else I should have done that actually works, without craahing?

You should have a look at : http://www.sfml-dev.org/

Its a great way to learn C++

Its a 2D game library which is very easy to learn. Its cross-platform(Windows, OS X, Linux). The documentation is excellent and the guides to setting up for each environment are brilliant. You wont see better on the internet.

Google "SFML 2.0 made easy" for some good tutorials on how to use it. They are youtube tutorials. The current version of the library is 2.2, but the version 2.0 tutorials work with no problem. These tutorials are done with Visual Studio, but I followed them with XCode with no problems at all, so it wont make a difference what compiler you use as longs its one of the supported ones.

The tutorials are very short. They are aimed at beginners. Just about all the examples are done in the main method, so they arent complicated at all. Its really very easy to follow and the advantage of this library is that while learning, you get see stuff actually work on your computer.

A good challenge is converting working tutorial code which is all in the single main method to classes etc, so that you reuse them.

The guy doing these tutorials is also part of the dev team responsible for the library.

There are other tutorials on net for SFML, but be aware that most of them are for version 1.6 and there have been some significant changes. A nice challenge is converting the 1.6 code to 2.2 :)

Here is a link to the 1.6 source(he hsant put the v2 code in the repository) https://github.com/CodingMadeEasy/Sfml-1.6

Browse this to get an idea of simplicity of the library
 
Last edited:
The reason for this is that m[3] = *(m+3) = *(3+m) = 3[m]. In the case of a string literal, which is just an array of characters, this means that 6["Hello World"], will give you 'W', and &6["Hello World"], will give you the pointer to 'W' in the string, so that cout would print out "World".

Because of the offset from the and-ed pointer, which incidentally, can be anything from 0-3 inclusive, since char alignment only has to align to its element size, the output will be 'World', 'orld', 'rld' or 'ld'.
I have never seen anything in the standard that would indicate this.
 
Nice explanation, cguy, and at least now your riddle is accessible to people without years' experience (although the actual mechanics behind it are still unclear without that experience).

Here's a.more simple riddle: in the code I posted at the start (for my lottery generator), something is making the program crash when the enter is typed at the end (an action that is saved to a string before zeeo is.returned to signal the end of the program).

Is that's what's killing it - a string can't be empty? I only did that as a hack to stop the console window from closing at the end, after the program has finished running. Was there something else I should have done that actually works, without craahing?

Arcane problems like this will only be solved with a more sane programming language that isn't consigned to 8 - 10 different specifications. C# or similar will make your problem a hundred times easier to solve, in a nice form window, where you can actually show it to your boss or potential employer/random number enthusiast, etc ,etc
 
Nice explanation, cguy, and at least now your riddle is accessible to people without years' experience (although the actual mechanics behind it are still unclear without that experience).

Here's a.more simple riddle: in the code I posted at the start (for my lottery generator), something is making the program crash when the enter is typed at the end (an action that is saved to a string before zeeo is.returned to signal the end of the program).

Is that's what's killing it - a string can't be empty? I only did that as a hack to stop the console window from closing at the end, after the program has finished running. Was there something else I should have done that actually works, without craahing?

if you are using Visual Studio, ctrl-F5 will run your code and not close the console window
 
Nice explanation, cguy, and at least now your riddle is accessible to people without years' experience (although the actual mechanics behind it are still unclear without that experience).

Here's a.more simple riddle: in the code I posted at the start (for my lottery generator), something is making the program crash when the enter is typed at the end (an action that is saved to a string before zeeo is.returned to signal the end of the program).

Is that's what's killing it - a string can't be empty? I only did that as a hack to stop the console window from closing at the end, after the program has finished running. Was there something else I should have done that actually works, without craahing?
Exactly what are the symptoms and what errors are given?
 
I have never seen anything in the standard that would indicate this.

It's not exactly hidden:

5.2.1 Subscripting [expr.sub]
1 A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions
shall have the type “pointer to T” and the other shall have unscoped enumeration or integral type.
The result is an lvalue of type “T.” The type “T” shall be a completely-defined object type.62 The expression
E1[E2] is identical (by definition) to *((E1)+(E2)) [ Note: see 5.3 and 5.7 for details of * and + and 8.3.4
for details of arrays. — end note ]

The rest follows from the definition of addition in 5.3 (the part about adding a number to a pointer) - namely that it is commutative:
the expressions (P)+N (equivalently, N+(P))
 
Last edited:
It's not exactly hidden:



The rest follows from the definition of addition in 5.3 (the part about adding a number to a pointer) - namely that it is commutative:
Yes but it doesn't quite follow that *((E1)+(E2)) = E2[E1]. It may work on compilers that implement it like that as a shortcut but where strict type checking is done would likely result in an error.
 
Your code seems to work fine for me (Visual Studio Express 2010, 32-bit and 64-bit). It is fine for a string to be empty. My first thought would be that you corrupted the stack somehow, but I can't see where that may be happening.

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.

For anybody who trusts me, you can download the actual .exe file from Google Drive by clicking here. If I've tried to infect you with a virus (which would be impressive for only my second ever C++ programme), may my groin be infested with a million fleas.

UPDATE: I decided to check it out in Microsoft Visual Studio's debugging mode, and it identified the error like this: "Unhandled exception at 0x00FF243D in HelloWorld.exe: Stack cookie instrumentation code detected a stack-based buffer overrun."

I find it really weird, because it gets all the way here quite happily (the text prints out fine and it waits for a response:
Code:
cout << "Press Enter again to exit." << endl;
	getline(cin, userRequest);

	return 0;
Press enter, though, and all hell breaks loose. I've tried a stack of things, from defining a fake value for userRequest just before to just after the actual user input is captured, but nothing works there.

The two questions then are:
1: Why is this happening?
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!
 
Assuming userRequest to be your string pointer use
Code:
cin >> userRequest;
instead.

I'm also assuming userRequest to be correctly defined as a char string.
 
Assuming userRequest to be your string pointer use
Code:
cin >> userRequest;
instead.

I'm also assuming userRequest to be correctly defined as a char string.

No, userRequest was defined as a string:

string userRequest;

Later on I used this to convert it to an integer, so that my loops at the top could process the number of draws a user requested at the start:

int linesNeeded = atoi(userRequest.c_str());

*shrugs* Don't ask me why, and it worked at least (apart from the total crash at the end lol).

Is that a bad thing?
 
Yes but it doesn't quite follow that *((E1)+(E2)) = E2[E1]. It may work on compilers that implement it like that as a shortcut but where strict type checking is done would likely result in an error.

It does exactly follow, since as I said, the spec says that addition of a pointer and an integral type is commutative. The only type requirement (as I highlighted in bold), is that one is a pointer, and the other is integral - it doesn't matter which order. A compiler than doesn't do this, is not standard compliant.
 
Last edited:
Top
Sign up to the MyBroadband newsletter
X