了解有关内存对齐的 C 程序
Understanding a C program about memory alignment
我正在通过以下 link 来理解内存对齐:https://www.ibm.com/developerworks/library/pa-dalign/#N10159。但是我无法理解下面给出的代码片段。
void Munge8( void *data, uint32_t size ) {
uint8_t *data8 = (uint8_t*) data;
uint8_t *data8End = data8 + size;
while( data8 != data8End ) {
*data8++ = -*data8;
}
}
这里的目的是增加指针,这本来可以由 "data8 = data8 + 1" 完成,但有问题的代码使用“*data8++ = -*data8”。它们都工作正常,即增加指针,但我无法理解后者背后的逻辑。比"data8 = data8+1"好吗?
在编译过程中出现错误 "alignment_test1.c:44: warning: operation on ‘data8’ may be undefined"。
问题的第二部分是关于下面的代码片段(来自前面提到的 link)。
清单 2. 一次处理两个字节的数据
void Munge16( void *data, uint32_t size ) {
uint16_t *data16 = (uint16_t*) data;
uint16_t *data16End = data16 + (size >> 1); /* Divide size by 2. */
uint8_t *data8 = (uint8_t*) data16End;
uint8_t *data8End = data8 + (size & 0x00000001); /* Strip upper 31 bits. */
while( data16 != data16End ) {
*data16++ = -*data16;
}
while( data8 != data8End ) {
*data8++ = -*data8;
}
}
第二个 'while' 循环背后的原因可能是什么?因为在这种情况下 data8 和 data8End 总是相同的。
那篇文章中的代码是一团乱麻。不要阅读或研究它。立即停止阅读文章。
*data8++ = -*data8;
调用未定义的行为,因为它包含对 data8
的无序访问。查看有史以来最常见的 C 语言常见问题解答:Why are these constructs (using ++) undefined behavior?
根据数据的原始类型,第二部分很可能包含各种形式的严格别名行为,这是另一种形式的未定义行为。您不能将指向某物的指针转换为 pointer-to-uint16_t,然后像访问 uint16_t
、 一样访问内容,除非 是对象的原始类型(有效类型)。这将我们引向另一个常见的 C 常见问题解答,What is the strict aliasing rule?
您可以将那篇文章的作者指向这些链接,告诉他们先学习基本的 C 编程,然后再尝试在 Internet 上发布技术文章。
我正在通过以下 link 来理解内存对齐:https://www.ibm.com/developerworks/library/pa-dalign/#N10159。但是我无法理解下面给出的代码片段。
void Munge8( void *data, uint32_t size ) {
uint8_t *data8 = (uint8_t*) data;
uint8_t *data8End = data8 + size;
while( data8 != data8End ) {
*data8++ = -*data8;
}
}
这里的目的是增加指针,这本来可以由 "data8 = data8 + 1" 完成,但有问题的代码使用“*data8++ = -*data8”。它们都工作正常,即增加指针,但我无法理解后者背后的逻辑。比"data8 = data8+1"好吗?
在编译过程中出现错误 "alignment_test1.c:44: warning: operation on ‘data8’ may be undefined"。
问题的第二部分是关于下面的代码片段(来自前面提到的 link)。
清单 2. 一次处理两个字节的数据
void Munge16( void *data, uint32_t size ) {
uint16_t *data16 = (uint16_t*) data;
uint16_t *data16End = data16 + (size >> 1); /* Divide size by 2. */
uint8_t *data8 = (uint8_t*) data16End;
uint8_t *data8End = data8 + (size & 0x00000001); /* Strip upper 31 bits. */
while( data16 != data16End ) {
*data16++ = -*data16;
}
while( data8 != data8End ) {
*data8++ = -*data8;
}
}
第二个 'while' 循环背后的原因可能是什么?因为在这种情况下 data8 和 data8End 总是相同的。
那篇文章中的代码是一团乱麻。不要阅读或研究它。立即停止阅读文章。
*data8++ = -*data8;
调用未定义的行为,因为它包含对 data8
的无序访问。查看有史以来最常见的 C 语言常见问题解答:Why are these constructs (using ++) undefined behavior?
根据数据的原始类型,第二部分很可能包含各种形式的严格别名行为,这是另一种形式的未定义行为。您不能将指向某物的指针转换为 pointer-to-uint16_t,然后像访问 uint16_t
、 一样访问内容,除非 是对象的原始类型(有效类型)。这将我们引向另一个常见的 C 常见问题解答,What is the strict aliasing rule?
您可以将那篇文章的作者指向这些链接,告诉他们先学习基本的 C 编程,然后再尝试在 Internet 上发布技术文章。