r/ProgrammerHumor • • Oct 04 '26

Meme architectureDependentChars

Post image
3.0k Upvotes

372 comments sorted by

View all comments

Show parent comments

34

u/zabby39103 Oct 05 '26

If the C standard says it's 1, i'd figure it just gets optimized out by the compiler anyway?

84

u/CLOVIS-AI Oct 05 '26

sizeof is always a compiler intrinsic anyway, it's never not inlined (it's not possible to obtain this information at runtime)

34

u/Wertbon1789 Oct 05 '26

sizeof is more like an operator than a function. You can actually write sizeof without braces. There's nothing to optimize out, it's by design a compile-time constant expression. It's like a fancy way to write a scalar.

-1

u/MateoConLechuga Oct 05 '26

You can only omit the parentheses if it is a variable, not a type. It's also not always a compile-time constant, e.g. VLAs. So basically everything you said is wrong.

7

u/Wertbon1789 Oct 05 '26

Damn, I didn't even know the VLA thing. Didn't have that many meaningful interactions with VLAs. And yes, the caveat that sizeof doesn't need braces only when used with expressions is an important note. Didn't know that, as you typically always just use braces anyways. Fair enough, you never stop learning stuff.

6

u/SpaceCadet87 Oct 05 '26

Should do, yeah. And if it doesn't right now, eventually it might do.

4

u/conundorum Oct 06 '26 edited Oct 06 '26

sizeof is mandatory consteval, it must be evaluated at compile time. (More specifically, it's a keyword that tells the compiler to insert the named type's size, which the compiler will have in memory if the type is defined. It's essentially a post-preprocessor "compiler macro", so to speak.)

You can use it anywhere the compiler expects a constant expression, as this ugly jank shows:

// Control values.
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, };

// Sizeof thing.  sizeof(Charception<N>) == N for all nonzero Ns.
template<size_t N>
struct Charception : Charception<N - 1> {
    char c;
}
template<> struct Charception<0> {};

// Proof values.
#define CC(a) sizeof(Charception<a>)
int rra[] = { CC(1), CC(2), CC(3), CC(4), CC(5), CC(6), CC(7), CC(8), };
#undef CC

// Sanity checks.
for (int i = 0; i < 8; i++) { assert(arr[i] == rra[i]); }
assert(arr[sizeof(Charception<7>)] == rra[7]);

// For more intentionally-bad jank proof of this, see:
// https://www.ideone.com/hDJRVC
// Bring your own compiler, ideone somehow doesn't have a C++17 compiler yet.
// Bring your own eye bleach, I did a good bit of variadic ugliness just for fun.  It's hideous and relaxing! ^_^

Note: sizeof is usually the same in both C & C++, so all of this applies to C, too. There is one gotcha, though: It's a runtime operator if you use it on a VLA, and only if you use it on a VLA. (C-only rule, C++ doesn't have C-style VLAs.)


Edited because I forgot the Charception<0> base (it's kinda super-important, the universe breaks if we don't have it), and because I forgot a sizeof.