Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

245
Visualizações
Have I applied the rule of strict aliasing correctly?

My current (simplified) buffer API looks like this:

typedef struct {
    size_t offset;
    size_t size;
    uint8_t *data;
} my_buffer;

// Writes an unsigned int 8 to the buffer
bool my_buffer_write_u8(my_buffer *buffer, uint8_t value) {
    if (buffer->offset >= buffer->size) return false;

    buffer->data[buffer->offset] = value;
    ++buffer->offset;
    return true;
}

However, after refreshing my knowledge about the strict aliasing rule in C I'm not so sure about this use case:

    char string[32];

    my_buffer buffer;
    buffer.size = sizeof(string);
    buffer.data = string; // <-- I think this violates the strict aliasing rule
    buffer.offset = 0;

    // the function calls access buffer.data which is defined to be `uint8_t *` and not `char *`
    // in other words, I'm manipulating a `char *` through a `uint8_t *`:
    // even though uint8_t is almost always unsigned char, it is nevertheless not the same as unsigned char
    my_buffer_write_u8(&buffer, 'h');
    my_buffer_write_u8(&buffer, 'e');
    my_buffer_write_u8(&buffer, 'l');
    my_buffer_write_u8(&buffer, 'l');
    my_buffer_write_u8(&buffer, 'o');
    my_buffer_write_u8(&buffer, '\0');

I think I should be using void * in the buffer struct and use a (char *) cast to access the underlying data:

typedef struct {
    size_t offset;
    size_t size;
    void *data;
} my_buffer;

// Writes an unsigned int 8 to the buffer
bool my_buffer_write_u8(my_buffer *buffer, uint8_t value) {
    if (buffer->offset >= buffer->size) return false;

    unsigned char *data = (unsigned char *)buffer->data;

    data[buffer->offset] = value;
    ++buffer->offset;

    return true;
}

Because char *, unsigned char * and signed char * are always assumed to alias other datatypes.

The same cannot be said about uint8_t * (according to the standard that is)

If CHAR_BIT is 8 then this adjusted code with (void *) should do exactly the same as with the uint8_t version.

Now to the question: have I applied the rule of strict aliasing correctly?

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

It would be UB if uint8_t was different from unsigned char.Assuming uint8_t exists it is very unlikely because

  • CHAR_BIT is at least 8, see http://port70.net/~nsz/c/c11/n1570.html#5.2.4.2.1p1
  • unsigned char has no padding bits
  • unsigned char is the smallest addressable unit

However, the standard does not explicitly require that uint8_t is the same type as unsigned char. Therefore it's rather implementation defined.

Consider applying solution from following thread to check it forementioned types are the same. How to assert two types are equal in c?

It is preferable to use char*/unsigned char* for accessing the data. However, if refactoring of the code would be cumbersome then just add a check if the types uint8_t and unsigned char are the same and reject compilation if not.

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda