There's something to be said to be familiar enough with the optimization that you can predict assembly that is not a direct translation of what you're writing.
For instance, when writing a scalar-processing loop over a fixed length array with no dependency between iterations you can reasonably expect the compiler to convert to SIMD instructions and do some unrolling. It's not too difficult to check the binary that this happened, and if it doesn't happen you just write it yourself with intrinsics.
I often think of C + compiler's optimization passes as a "scripting language for assembly".
In some cases you may wish to, yes. Particularly where it comes to things like explicitly zeroing memory before freeing it, something that has recently been addrezsed with memset_s
That's exactly my point: when the compiler can decide not to do something you told it to you don't have full explicit control over everything. That's not a bad thing though - the compiler usually makes good decisions on your behalf. Usually.
For instance, when writing a scalar-processing loop over a fixed length array with no dependency between iterations you can reasonably expect the compiler to convert to SIMD instructions and do some unrolling. It's not too difficult to check the binary that this happened, and if it doesn't happen you just write it yourself with intrinsics.
I often think of C + compiler's optimization passes as a "scripting language for assembly".