Is C++ too complex?

Started by
121 comments, last by Vortez 11 years, 3 months ago
I think the main issue with header files is that you're writing the same stuff twice (e.g. function prototypes vs. function definitions).

Also tried to look up the pointer stuff in C++, and ended up stumbling upon this instead:
http://en.wikipedia.org/wiki/C%2B%2B11#Null_pointer_constant

Gotta admit I didn't think of that one. That's really annoying. (then again, why would you have a function overloaded both to an integer and a pointer at the same time?)
Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.
Advertisement
People who dislike the compilation model may want to look out for (or even give feedback to the standards committee on) proposals for Modules. There have been proposals mentioning partial classes for easier code-gen tooling as well, but I don't know whether this is part of the Modules working group or separate at this point.
[size="1"]

Gotta admit I didn't think of that one. That's really annoying. (then again, why would you have a function overloaded both to an integer and a pointer at the same time?)
void processListNodes(node *begin, node *end);
void processListNodes(node *begin, int howMany);

I'm not arguing that this is or isn't good design, but it is something many people could plausibly write.

[quote name='Sik_the_hedgehog' timestamp='1354779033' post='5007664']
Actually, decided to take a look to it, and I think the answer for 1.1 (and thereby 1.2 potentially) may be wrong. That thing is pure pointer arithmetic which should be well defined really
Yes, it should be well defined, but it's not (maybe this has changed in C++11, I've not re-checked the spec). You're allowed to point to "one past the end" of an array, but no further than that.
In practice, it works fine, but a compliant compiler is allowed to do whatever it likes if you ask for a pointer that's "two past the end" of an array.
[/quote]

All true. Although probably no compiler is going to give you trouble for this one, I was recently surprised when gcc turned this code into an infinite loop:
for (int i = 0; i >= 0; ++i) {
}


A more naive compiler would stop once i overflows and becomes a large negative number, but what happens after overflow is undefined behavior, so the compiler can assume that it won't happen (if it does, it's allowed to do anything it wants so any behavior is correct) and can therefore optimize `i >= 0' to `true'.

This kind of strict interpretation of the standard by the compiler makers is annoying. For instance, a C++98-compliant compiler can put an infinite loop at the end of a hello-world program, because the standard doesn't specify "finishing in a finite amount of time" as part of the observable behavior of the program. The return value of the program is also not part of the observable behavior, so I think a compiler could stay compliant while returning 3 from main every time, regardless of what the code says. Of course nobody would use a compiler that did that, but it illustrates the point that simply satisfying the standard is a low bar and I expect my compiler to be more reasonable than that.
Yeah, GCC generates that kind of code on purpose. Try to check for overflow after the fact (e.g. by checking if the value went negative), GCC will explicitly optimize out (i.e. remove) the check. The reasoning behind this is that "it's undefined behavior so we'll try to break the code so you can't rely on it", except sometimes that can backfire since that kind of bugs on purpose may not pop up in ages, depending on the situation.


[quote name='Sik_the_hedgehog' timestamp='1354786764' post='5007694']
Gotta admit I didn't think of that one. That's really annoying. (then again, why would you have a function overloaded both to an integer and a pointer at the same time?)
void processListNodes(node *begin, node *end);
void processListNodes(node *begin, int howMany);

I'm not arguing that this is or isn't good design, but it is something many people could plausibly write.
[/quote]
Fair enough.
Don't pay much attention to "the hedgehog" in my nick, it's just because "Sik" was already taken =/ By the way, Sik is pronounced like seek, not like sick.

Yeah, GCC generates that kind of code on purpose. Try to check for overflow after the fact (e.g. by checking if the value went negative), GCC will explicitly optimize out (i.e. remove) the check. The reasoning behind this is that "it's undefined behavior so we'll try to break the code so you can't rely on it", except sometimes that can backfire since that kind of bugs on purpose may not pop up in ages, depending on the situation.


It takes a bit of a sadist to come up with that method to educate programmers.

How about a warning saying something like "this conditional expression evaluates to true unless you invoke undefined behavior"? If I am compiling some old piece of code that is now broken because the compiler is now a lawyer, I would much rather get an informative message than a bug.
From what I've heard, it wasn't a deliberate attempt to punish people who rely on undefined behavior, but just a consequence of a change to the optimizer to generate faster code. It just so happens that it looks like an attempt to piss off people who rely on undefined behavior. Fortunately, gcc offers a flag to disable this optimization: -fwrapv.

Anyways, for a less contrived example of overloading a pointer and an integer:

ostream & operator<<(int);
ostream & operator<<(const void *);
// along with half a million other member overloads and some non-member overloads

Anyways, for a less contrived example of overloading a pointer and an integer:

ostream & operator<<(int);
ostream & operator<<(const void *);
// along with half a million other member overloads and some non-member overloads



Yeah, that one is responsible for this fun piece of code:
#include <iostream>

int main() {
volatile char s[] = "Hello, world!";
std::cout << s << '\n';
}


At least recent versions of g++ give you a reasonable warning about this one.

Interesting.
The clear separation of a declaration and an implementation is one of the things I really like with C and C++.
The header file has (should have) everything I need as a _user_ of the class, and nothing more.
Makes the intention of the class very clear, and then I can "hide" the implementation in a cpp file.

Except that the header file also contains information about private member variables and methods. So you either give the client all the details about the class, or you end up using something like pimpl, which is yet another hoop to jump through that other languages have realised provides no tangible benefit.


Also, this separation is not mandatory, if you want, you can write everything in the same file too. Just gets more messy tongue.png
I really dislike how Java forces me to put everything in the same file...
Very hard to get an overview of the class without additional tools like a smart IDE or doxygen...


So? This isn't the 80's anymore. We don't have to program in vi and cc on the command line. Realistically, managing any project of a decent size without an IDE is just making work for no reason.
if you think programming is like sex, you probably haven't done much of either.-------------- - capn_midnight

[quote name='SiCrane' timestamp='1354812511' post='5007802']
Anyways, for a less contrived example of overloading a pointer and an integer:

ostream & operator<<(int);
ostream & operator<<(const void *);
// along with half a million other member overloads and some non-member overloads



Yeah, that one is responsible for this fun piece of code:
#include <iostream>

int main() {
volatile char s[] = "Hello, world!";
std::cout << s << '\n';
}


At least recent versions of g++ give you a reasonable warning about this one.
[/quote]
I ran into one of these on a function call in optimised code where the compiler had optimised away the actual instance we were interested in being passed to the function, that was a fun few days to track that down.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

This topic is closed to new replies.

Advertisement