Live data from Hacker News

Ill-Advised C++ Rant, Part 2

codersnotes.com

11–20 of 66 posts

Re: Ill-Advised C++ Rant, Part 2

#11
post #4

do you realize this would crash with empty array: #define countof(X) (sizeof(X) / sizeof((X)[0]))

No, because the expression is not evaluated at any time. Only the type of the expression is used. A much better implementation would be using std::begin, std::end; #define countof(x) (end(x) - begin(x)) (except for the double evaluation, but this is better as a template function instead of a macro anyway) because it'll work on any type that supports random-access iterators which include arrays but also std::array and…

Corrected below, leaving here for posterity and to make sure this conversation isn't confusing in the future. The only thing I'll note is that you get a compile error on a zero length array, so the OP of this chain turns out right in a way heh.

Start ignoring here: Are you suggesting end() and begin() can be called on an array? As far as I know they can't. Apparently you can deduce array length in a constexpr function now in C++11 (which I only learned just now but also couldn't get working quickly, so have some salt with that), but before that arrays always degrade to pointers when passed as function arguments so there's (afaik) no way to extract their length from their type...

Re: Ill-Advised C++ Rant, Part 2

#13
post #4

Earlier quoted context omitted.

No, because the expression is not evaluated at any time. Only the type of the expression is used. A much better implementation would be using std::begin, std::end; #define countof(x) (end(x) - begin(x)) (except for the double evaluation, but this is better as a template function instead of a macro anyway) because it'll work on any type that supports random-access iterators which include arrays but also std::array and…

Corrected below, leaving here for posterity and to make sure this conversation isn't confusing in the future. The only thing I'll note is that you get a compile error on a zero length array, so the OP of this chain turns out right in a way heh. Start ignoring here: Are you suggesting end() and begin() can be called on an array? As far as I know they can't. Apparently you can deduce array length in a constexpr functio…

Before the array decays to a pointer, you can get its length.

Here is the implementation of std::begin for arrays in libc++: https://github.com/llvm-mirror/libcxx/blob/60d223df071f6e3d4...

Re: Ill-Advised C++ Rant, Part 2

#14
post #13

Earlier quoted context omitted.

Corrected below, leaving here for posterity and to make sure this conversation isn't confusing in the future. The only thing I'll note is that you get a compile error on a zero length array, so the OP of this chain turns out right in a way heh. Start ignoring here: Are you suggesting end() and begin() can be called on an array? As far as I know they can't. Apparently you can deduce array length in a constexpr functio…

Before the array decays to a pointer, you can get its length. Here is the implementation of std::begin for arrays in libc++: https://github.com/llvm-mirror/libcxx/blob/60d223df071f6e3d4...

Quite right, I'm apparently rusty on my stdlib knowledge. Didn't know about the reference trick.

Re: Ill-Advised C++ Rant, Part 2

#15
post #4

Earlier quoted context omitted.

No, because the expression is not evaluated at any time. Only the type of the expression is used. A much better implementation would be using std::begin, std::end; #define countof(x) (end(x) - begin(x)) (except for the double evaluation, but this is better as a template function instead of a macro anyway) because it'll work on any type that supports random-access iterators which include arrays but also std::array and…

Corrected below, leaving here for posterity and to make sure this conversation isn't confusing in the future. The only thing I'll note is that you get a compile error on a zero length array, so the OP of this chain turns out right in a way heh. Start ignoring here: Are you suggesting end() and begin() can be called on an array? As far as I know they can't. Apparently you can deduce array length in a constexpr functio…

Yes you can call std::begin() and std::end() on an array.

    int a[] = {4,5,6};
    for(int i : a)
        ;
That is how the above works.

Re: Ill-Advised C++ Rant, Part 2

#17
post #4

do you realize this would crash with empty array: #define countof(X) (sizeof(X) / sizeof((X)[0]))

No, because the expression is not evaluated at any time. Only the type of the expression is used. A much better implementation would be using std::begin, std::end; #define countof(x) (end(x) - begin(x)) (except for the double evaluation, but this is better as a template function instead of a macro anyway) because it'll work on any type that supports random-access iterators which include arrays but also std::array and…

Does this work at compile-time?

One of the uses for countof is (somewhat ironically) doing a enum->string table where you want to enforce the table gets manually updated properly:

    enum Color { red, green, blue, num_colors };
    const char *color_string[] = { "red", "green", "blue" };

    static_assert(countof(color_string) == num_colors);

Re: Ill-Advised C++ Rant, Part 2

#19
post #17
post #4

Earlier quoted context omitted.

No, because the expression is not evaluated at any time. Only the type of the expression is used. A much better implementation would be using std::begin, std::end; #define countof(x) (end(x) - begin(x)) (except for the double evaluation, but this is better as a template function instead of a macro anyway) because it'll work on any type that supports random-access iterators which include arrays but also std::array and…

Does this work at compile-time? One of the uses for countof is (somewhat ironically) doing a enum->string table where you want to enforce the table gets manually updated properly: enum Color { red, green, blue, num_colors }; const char *color_string[] = { "red", "green", "blue" }; static_assert(countof(color_string) == num_colors);

No, it doesn't, which is why I said this is better implemented with a template :)

Re: Ill-Advised C++ Rant, Part 2

#20
I tend to agree, but gave up on fixing C++ a decade ago.

I hope Rust is the future; it deals with all these issues. But Rust seems to be starting out at the complexity level it took C++ two decades to achieve.

Post reply on HN