So, in your example technically there is no difference whatsoever. Because it is hard to find a compiler that will not optimize operations on literals like -1
and ~0
. With your example I've got exactly:
; ...
movq $-1, -16(%rbp)
movq $-1, -8(%rbp)
; ...
Don't be afraid of those -1
's, assebmly is typeless ;)
More interesting question is if your example would be:
#include <stddef.h>
int main() {
int var0 = 0;
int var1 = 1;
size_t a = (size_t) -var1;
size_t b = (size_t) ~var0;
return a ^ b;
}
In my case (Kubuntu, gcc 4.8.2, x86_64, -O0
option) the part of interest was:
movl $0, -24(%rbp) ; var0 = 0
movl $1, -20(%rbp) ; var1 = 1
movl -20(%rbp), %eax
negl %eax ; 2's complement negation
; ...
movl -24(%rbp), %eax
notl %eax ; 1's complement negation
; ...
Looking into Intel's manual:
NEG
- Two's Complement Negation
Replaces the value of operand (the destination operand) with its
two's complement. (This operation is equivalent to
subtracting the operand from 0.)
NOT
- One's Complement Negation
Performs a bitwise NOT operation (each 1 is set to 0, and each 0
is set to 1) on the destination operand and stores
the result in the destination operand location.
My conclusion would be, theoretically, code could differ on some exotic platform and compiler, but otherwise – no. And always if unsure check assembly listing on your platform.