Strict anti-aliasing rule and strlen glibc implementation

I read for a while about the strictest aliasing rule, and I'm starting to get very confused. First of all, I read these questions and a few answers:

According to them (as I understand it) access to the buffer charusing a pointer to another type violates the strict anti-aliasing rule. However, the glibc implementation strlen()has the following code (with comments and removal of the 64-bit implementation):

size_t strlen(const char *str)
{
    const char *char_ptr;
    const unsigned long int *longword_ptr;
    unsigned long int longword, magic_bits, himagic, lomagic;

    for (char_ptr = str; ((unsigned long int) char_ptr 
             & (sizeof (longword) - 1)) != 0; ++char_ptr)
       if (*char_ptr == '\0')
           return char_ptr - str;

    longword_ptr = (unsigned long int *) char_ptr;

    himagic = 0x80808080L;
    lomagic = 0x01010101L;

    for (;;)
    { 
        longword = *longword_ptr++;

        if (((longword - lomagic) & himagic) != 0)
        {
            const char *cp = (const char *) (longword_ptr - 1);

            if (cp[0] == 0)
                return cp - str;
            if (cp[1] == 0)
                return cp - str + 1;
            if (cp[2] == 0)
                return cp - str + 2;
            if (cp[3] == 0)
                return cp - str + 3;
        }
    }
}

longword_ptr = (unsigned long int *) char_ptr;, , a unsigned long int char. , . , , , , .

:

, , char , .

, , - -fno-strict-aliasing, ? -, glibc, - , - , , . , , - , .

+6
4

ISO C . ( , , ). ISO C. C. , .

, C- GNU, , .

+8

, , , . C , , , - (, ) , , .

, , , , , , . , , , . , - , . , , C, , , , , .

+3

, : C , - . , char* unsigned long*, , char* unsigned long, .

: , strlen() , . , , , unsigned long* . strlen()

short myString[] = {0x666f, 0x6f00, 0};
size_t length = strlen((char*)myString);    //implementation now invokes undefined behavior!

strlen() - undefined, strlen(), strlen(). , strlen() , , - , strlen() , undefined , strlen().

, , " undefined", , char* - , , . , . , . C undefined.

, , ( , (unsigned long int) char_ptr & (sizeof (longword) - 1)). char* , unsigned long*.

, C, C , . gcc , , glibc , gcc , .

, C . strlen() , , malloc()/free() Foo Bar. malloc() malloc(), . C .

0

The underlying assumption is probably that the function is separately compiled and not available for embedding or other optimizations of cross functions. This means that no compile-time information flows inside or outside the function.

The function does not try to change anything with a pointer, so there is no conflict.

-3
source

All Articles