SUMMARY Defensive code can use assertions around uninitialised values to protect against undefined behaviour. While valgrind does the same thing, to do both there is now a different compile option to test under valgrind. STEPS TO REPRODUCE 1. t.c #include <assert.h> int main() { unsigned long n; char *b = (char *) &n; *b = 1; assert((n & ~0xFFUL) == 0); } 2. gcc -o /tmp/t /tmp/t.c 3. valgrind /tmp/t OBSERVED RESULT ==1111332== Conditional jump or move depends on uninitialised value(s) ==1111332== at 0x401147: main (in /tmp/t) EXPECTED RESULT no error. SOFTWARE/OS VERSIONS Linux (Fedora 40) (gcc 14.1.1) ADDITIONAL INFORMATION This didn't trigger as error on valgrind 3.18.1. ref: https://jira.mariadb.org/browse/MDEV-34502 and workaround: https://github.com/MariaDB/server/pull/3378 notably: valgrind didn't error on the subsequent statements reading n
First, are you certain that it was only the change from Valgrind 3.18.1 to Valgrind 3.23 that caused the change? I just checked out the code for 3.18.1 and using GCC 14.1 on RHEL 7..6 I get the same error with both that version and git HEAD. Second, there is no way for us to know when an expression is used in an assert. On amd64 your example code produces 40114a: c6 00 01 movb $0x1,(%rax) 40114d: 48 8b 45 f0 mov -0x10(%rbp),%rax 401151: 48 3d ff 00 00 00 cmp $0xff,%rax 401157: 76 19 jbe 401172 <main+0x3c> 401159: b9 23 20 40 00 mov $0x402023,%ecx 40115e: ba 09 00 00 00 mov $0x9,%edx 401163: be 04 20 40 00 mov $0x402004,%esi 401168: bf 10 20 40 00 mov $0x402010,%edi 40116d: e8 be fe ff ff call 401030 <__assert_fail@plt> 401172: b8 00 00 00 00 mov $0x0,%eax 401177: c9 leave 401178: c3 ret where the opcodes 401151: 48 3d ff 00 00 00 cmp $0xff,%rax 401157: 76 19 jbe 401172 <main+0x3c> are triggering the error. At the moment of the error we can't tell that the false case leads to a call to __assert_fail. Thirdly, and this is the really fundamental problem, you don't seem to understand the nature of Undefined Behaviour. There are two possibilities. Either your program text is well-formed or it is ill-formed. If it is well-formed then you can reason about it. You can say things like "if A is true then B should happen". If it is ill-formed then that is it. You cannot reason about ill-formed code. See https://en.cppreference.com/w/c/language/behavior and https://youtu.be/yG1OZ69H_-o?feature=shared So, in summary 1. this would be difficult to impllement 2. I think that it would be a serious mistake for us to do anything that masks UB.
Might have been a compiler change. Agree with other statements. Thanks for your time.