Zitat:vermutlich daher undefiniertes Verhalten (bei höheren Optimierungsstufen)
wäre interessant ob der "-fsanitize=undefined" das aufzeigt - ich denke ein Coverity hätte das auch bemängelt
update: "-fsanitize=undefined" zeigt da nix mit -O0 oder höher, hab einfach den Borland-Code - also die 3-4 Routinen kopiert - das Ergebnis ändert sich ständig aber sanitizer schlägt nicht an - kann aber auch an mir liegen
der neue TypeSanitizer "-fsanitize=type" findet was, ist aber auch noch sehr experimentell
https://clang.llvm.org/docs/TypeSanitizer.html
Code:
clang++ -fsanitize=type -fno-omit-frame-pointer -g -O0 test.cpp -o testbekommt man für diesen Code (TypeSanitizer findings als Kommentar) folgende Ausgaben
Code:
#include <stdint.h>
static inline uint8_t readb(uint8_t *p)
{
return ((uint8_t)*p);
}
static inline int16_t readws(uint8_t *p)
{
return ((int16_t)(readb(p + 1) << 8) | (readb(p)));
}
uint16_t swap_u16(const uint16_t val)
{
return (val << 8) | (val >> 8);
}
static inline int32_t readds(uint8_t *p)
{
return ((int32_t)(readws(p + 2) << 16) | readws(p));
}
static inline uint32_t swap32_bor(uint32_t v){
/*register*/ signed int tmp;
int16_t a[2];
int32_t *ptr = (int32_t*)(&a[0]);
*ptr = readds((uint8_t*)&v);
tmp = a[0]; // <== TypeSanitizer: type-aliasing-violation on address
a[0] = swap_u16(a[1]); // <== TypeSanitizer: type-aliasing-violation on address
a[1] = swap_u16(tmp); // <== TypeSanitizer: type-aliasing-violation on address
return readds((uint8_t*)ptr);
}
int main() {
return swap32_bor(0x12345678);
}Ausgabe
Code:
==13160==ERROR: TypeSanitizer: type-aliasing-violation on address 0x7ffe1e8763b4 (pc 0x5b2bbc0665f8 bp 0x7ffe1e876280 sp 0x7ffe1e876210 tid 13160)
READ of size 2 at 0x7ffe1e8763b4 with type short accesses an existing object of type int
#0 0x5b2bbc0665f7 in swap32_bor(unsigned int) /home/linux/temp/swap32_speed/test.cpp:30:8
==13160==ERROR: TypeSanitizer: type-aliasing-violation on address 0x7ffe1e8763b6 (pc 0x5b2bbc06682f bp 0x7ffe1e876280 sp 0x7ffe1e876210 tid 13160)
READ of size 2 at 0x7ffe1e8763b6 with type short accesses part of an existing object of type int that starts at offset -2
#0 0x5b2bbc06682e in swap32_bor(unsigned int) /home/linux/temp/swap32_speed/test.cpp:31:18
==13160==ERROR: TypeSanitizer: type-aliasing-violation on address 0x7ffe1e8763b4 (pc 0x5b2bbc066930 bp 0x7ffe1e876280 sp 0x7ffe1e876210 tid 13160)
WRITE of size 2 at 0x7ffe1e8763b4 with type short accesses an existing object of type int
#0 0x5b2bbc06692f in swap32_bor(unsigned int) /home/linux/temp/swap32_speed/test.cpp:31:7
==13160==ERROR: TypeSanitizer: type-aliasing-violation on address 0x7ffe1e8763b6 (pc 0x5b2bbc066b68 bp 0x7ffe1e876280 sp 0x7ffe1e876210 tid 13160)
WRITE of size 2 at 0x7ffe1e8763b6 with type short accesses part of an existing object of type int that starts at offset -2
#0 0x5b2bbc066b67 in swap32_bor(unsigned int) /home/linux/temp/swap32_speed/test.cpp:32:7d.h. der TypeSanitizer kommt jetzt auch auf meine Liste also: -fsanitize=address, =thread, =undefined und =type

leider ist der =memory so kompliziert zu nutzen wegen den 3rd-parties (aber Schick ist da ja angenehm bescheiden) - da bleibt aber noch der valgrind - auch wenn er 100x langsamer ist

die Sanitizer werden ständig verbessert oder es kommen neue hinzu - wenn man sicher gehen will sollte man die Kompiler immer schön aktuell halten - SUSE Tumbleweed/Fedora oder Arch-Linux sind da immer recht fix mit Update auf die neuen Releases

