On 2026-03-19 I wrote:
> Developer Studio supports #pragmas to control aliasing.[3] However, my
> alias.c test program doesn't "miscompile" with Developer Studio 12.6.
> I tried setting -xalias_level=std and even =strong at -O5 optimization
> level (-O3 or higher is needed for inlining to happen at all). Thus, I
> couldn't test if a #pragma would make a difference.

It might be that everything is assumed to alias when a function is
called, even if it is an inline function that is fully inlined. That
would explain why alias.c doesn't misbehave. I didn't find any docs
about this behavior.

The attached program avoids inline functions. Now the aliasing rules
make a difference. A #pragma can be used to make type punning work when
aliasing rules are enabled.

The above matters only when -xalias_level has been used to enable the
aliasing rules. The default is -xalias_level=any which is equivalent to
-fno-strict-aliasing in GCC and Clang. So aligned type punning without
any pragmas should be safe by default with the Studio 12.6 compiler.

I couldn't find any other method than type punning (like some
__attribute__ or #pragma) that would produce fast aligned loads and
stores.

I don't know if handling this specially in Gnulib is worth it, but I
thought I share the information in any case.

-- 
Lasse Collin
// Tested on cfarm216.cfarm.net.
//
// By default, any aliasing is allowed (like -fno-strict-aliasing).
// Enable standard aliasing rules:
// /opt/developerstudio12.6/bin/cc -O5 -xalias_level=std -std=c11 alias-solaris.c
//
// Non-standard overly-strict aliasing:
// /opt/developerstudio12.6/bin/cc -O5 -xalias_level=strong -std=c11 alias-solaris.c

#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>

int
main(void)
{
    unsigned char *buf = malloc(4);
    if (buf == NULL)
        return 1;

    uint32_t *buf32 = (uint32_t *)buf;
    uint16_t *buf16 = (uint16_t *)(buf + 2);

    // List all pointers that can alias in a single pragma:
    #pragma alias (buf, buf16, buf32)

    // Split pragmas don't work:
    // #pragma alias (buf, buf16)
    // #pragma alias (buf, buf32)

    *buf32 = 0x13121110;
    *buf16 = 0xF3F2;
    uint32_t v = *buf32;

    printf("v = 0x%08" PRIX32 "\n", v);

    for (size_t i = 0; i < 4; ++i)
        printf("0x%X\n", buf[i]);

    free(buf);

    return 0;
}

Reply via email to