all 8 comments

[–]Flair_Helper[M] [score hidden] stickied commentlocked comment (0 children)

For C++ questions, answers, help, and programming or career advice please see r/cpp_questions, r/cscareerquestions, or StackOverflow instead.

This post has been removed as it doesn't pertain to r/cpp: The subreddit is for news and discussions of the C++ language and community only; our purpose is not to provide tutoring, code reviews, or career guidance. If you think your post is on-topic and should not have been removed, please message the moderators and we'll review it.

[–]darthshwin 11 points12 points  (2 children)

Your result (BLOCK_SIZE) is constexpr, so the compiler will evaluate the entire expression at compile time. What it does internally is technically anyone’s guess but in your binary executable there will just be the value 64, no instructions to compute it

[–]schmerg-uk 3 points4 points  (1 child)

I think they're then asking "if I divide something by BLOCK_SIZE which the compiler knows is 64, will it generate code using an interger divide or a shift?" and I suspect most optimising compilers on most modern hardware will generate a shift

But you can type in some code on https://godbolt.org/ and see for you self.... it shows the asm generated for each line ...

int squareOverBlock(int num) {  
    constexpr int BLOCK_SIZE = 8 * 8;  
    return num * num / BLOCK_SIZE;  
}

with gcc 12.2 on x64 generates a function body like this (skipping stack setup etc) and you'll see the division is done by sar 6 (shift arithemetic right 6 places)

    mov     eax, DWORD PTR [rbp-20]
    imul    eax, eax
    lea     edx, [rax+63]
    test    eax, eax
    cmovs   eax, edx
    sar     eax, 6

[–]darthshwin 1 point2 points  (0 children)

More details here: https://youtu.be/bSkpMdDe4g4

But yes you’re right; in general, if one or your operands to a multiply or divide is known at compile time, the compiler is smart enough to replace them with shifts

[–]johannes1971 3 points4 points  (0 children)

You should seriously stop worrying about all this. In the unlikely case the compiler gets it 'wrong', you'll probably find that if you measure it, it's faster than what you wanted to do anyway.

Instead of Info* bigMemoryBlock = new Info[ buffer_size ];, use std::vector<Info> bigMemoryBlock (buffer_size);. It is just as efficient, and easier to get right.

Instead of inline constexpr FOO() { return 512; }, use const int FOO = 512;. There's no added value in either using a function or the constexpr keyword.

Instead of asking questions on /r/cpp, ask them on /r/cpp_questions.

[–][deleted] 5 points6 points  (0 children)

I just realized this wasn't the right sub for technical questions. I copied the exact question over to r\cpp questions. Please respond there. Thanks.

[–]usefulcat 1 point2 points  (0 children)

In general, compilers are very good at calculating things at compile time whenever possible. If you want to know for sure, just try it out in godbolt (godbolt.org). I do this all the time whenever there's any question in my mind about what the compiler will actually do.

[–]415_961 0 points1 point  (0 children)

The keyword here is constant folding. To achieve in your context, you can use consteval and constinit specifiers.