memset(key, 0, len) 다음에 free(key)가 오면 그건 지우기가 아니다. 그 버퍼를 다시 읽는 곳이 없으니 저장은 죽은 저장이고, 표준은 컴파일러가 그것을 버려도 된다고 한다. 5.1.2.3에 한 문장으로 있다. "An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced".
void drop_key(unsigned char *key, size_t len) {
memset(key, 0, len);
free(key);
}
x86-64 Linux 대상 clang -O2는 이걸 jmp free@PLT 하나로 만든다. memset은 사라진다. 소스를 읽으면 지우는 코드가 보인다. 바이너리에는 처음부터 없었다.
C11의 부록 K에는 맞는 문구가 있었다. memset_s는 "shall be evaluated strictly according to the rules of the abstract machine". 부록 K는 선택 사항이고 glibc는 끝내 넣지 않았다. C23은 memset_explicit을 <string.h>에 넣었다. 규범 본문은 목적이 "to make sensitive information stored in the object inaccessible"이라고 한다. 저장이 절대 생략되지 않는다는 부분은 그것을 "the intention"이라고 부르는 각주에 있는데, 각주는 규범이 아니다.
libc에 들어오기 전까지는 glibc와 BSD의 explicit_bzero, Windows의 SecureZeroMemory가 있다. 어느 것도 컴파일러가 레지스터나 스택에 남긴 사본까지는 닿지 않는다.