Pergunta

Por exemplo, se eu declarar uma variável longa, posso assumir que será sempre alinhado em um "sizeof (long)" fronteira? Microsoft Visual C ++ ajuda on-line diz isso, mas é o comportamento padrão?

Alguns mais informações:

a. É possível criar explicitamente um inteiro desalinhados (* bar):

de char foo [5]

int * bar = (int *) (& foo [1]);

b. Aparentemente, #pragma pack () afeta somente estruturas, classes e sindicatos.

c. estados documentação MSVC que tipos POD estão alinhados com seus respectivos tamanhos (mas é sempre ou por padrão, e ele é o comportamento padrão, eu não sei)

Foi útil?

Solução

Como já foi mencionado, isso não faz parte do padrão e é deixada para o compilador para implementar como lhe aprouver para o processador em questão. Por exemplo, VC poderia facilmente implementar diferentes requisitos de alinhamento para um processador ARM do que para x86 processadores.

implementos Microsoft VC o que é basicamente chamado alinhamento natural até o tamanho especificado pela directiva #pragma pack ou a opção de linha de comando / ZP. Isto significa que, por exemplo, qualquer tipo POD com um tamanho inferior ou igual a 8 bytes vão ser alinhadas com base no seu tamanho. Qualquer coisa maior será alinhado em um limite de 8 bytes.

Se é importante que você controlar o alinhamento para diferentes processadores e compiladores diferentes, então você pode usar um tamanho de embalagem de 1 e pad suas estruturas.

#pragma pack(push)
#pragma pack(1)    
struct Example
{
   short data1;     // offset 0
   short padding1;  // offset 2
   long data2;      // offset 4
};
#pragma pack(pop)

Neste código, a variável padding1 existe apenas para se certificar de que data2 é naturalmente alinhados.

Resposta a uma:

Sim, isso pode facilmente causar dados desalinhados. Em um processador x86, isso realmente não machucar muito em tudo. Em outros processadores, isso pode resultar em um acidente ou uma execução muito lenta. Por exemplo, o processador Alpha iria lançar uma exceção processador que seria capturado pelo sistema operacional. O sistema operacional seria, então inspecionar a instrução e, em seguida, fazer o trabalho necessário para lidar com os dados desalinhados. Em seguida, a execução continua. A palavra-chave __unaligned pode ser usado em VC para marcar acesso desalinhado para programas não-x86 (ou seja, para o CE).

Outras dicas

Por padrão, sim. No entanto, ele pode ser alterado através da #pragma pack ().

Eu não acredito que o padrão C ++ fazer qualquer exigência nesse sentido, e deixa para a implementação.

C e C ++ não definiu nenhum tipo de alinhamento. Mas alinhamento natural é o preferido por x86 e é necessário pela maioria das outras arquiteturas de CPU, e compiladores geralmente fazem o seu melhor para manter CPUs feliz. Assim, na prática você não vai ver um compilador gerar dados desalinhados menos que você realmente torcê-lo do braço.

Sim, todos os tipos estão sempre alinhados para, pelo menos, os seus requisitos de alinhamento.

Como poderia ser de outra forma?

Mas nota que o sizeof () um tipo não é a mesma que do alinhamento.

Você pode usar o seguinte macro para determinar os requisitos de alinhamento de um tipo:

#define ALIGNMENT_OF( t ) offsetof( struct { char x; t test; }, test )

Depende do compilador, os pragmas e o nível de otimização. Com compiladores modernos você também pode escolher tempo ou otimização de espaço, o que poderia alterar o alinhamento dos tipos também.

Geralmente, será porque a leitura / escrita a ele é mais rápido dessa forma. Mas quase todos os compilador tem um interruptor para desativar isso. Em gcc sua -malign - ???. Com os agregados que estão geralmente alinhados e dimensionado com base nos requisitos de alinhamento de cada elemento dentro.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top