[英]Is it ok to store an 8- or 16-bit value to a 16-bit aligned buffer in this code?
我想保存一些由8位指针指向16位对齐缓冲区的值(8或16位)。
extern volatile INT16U NvM_Zone[128] __attribute((nodp, addr(NVRAM1_PAGE1_FIRST_ADDRESS)));
Std_ReturnType NvM_WriteBlock(NvM_BlockIdType BlockId, INT8U *NvM_SrcPtr) {
Std_ReturnType Res = E_OK;
NvM_ConfigType *nvm_config = &NvMConfig;
NvM_StatusType nvm_status = nvm_config->nvm_module_status;
if ((nvm_status == NVM_COMPLETED)) {
nvm_status = NVM_IN_PROGRESS;
nvm_config->nvm_data_info = &g_NvmDataList[0];
INT8U i = nvm_config->nvm_data_info[BlockId].data_start_addr;
INT8U size = nvm_config->nvm_data_info[BlockId].data_size_in_byte;
if (size == 2) {
INT16U *src = (INT16U*)NvM_SrcPtr;
INT16U *dst = &NvM_Zone[i];
*dst = *src;
} else {
INT8U *src = NvM_SrcPtr;
INT16U *dst = &NvM_Zone[i];
*dst = (INT16U)(*src);
}
NVRAM_SavePage(0); // NVRAM_content : 0 ~ 63
NVRAM_SavePage(1); // NVRAM_content : 64 ~ 127
//NVRAM_SavePage(NVRAM2_PAGE1);
nvm_config->nvm_flash_cntr_in_rt++;
nvm_status = NVM_COMPLETED;
Res = E_OK;
} else {
Res = E_NOT_OK;
}
nvm_config->nvm_module_status = nvm_status;
return Res;
}
16位值-是否可以保存在8位指针中进行参数化(违反对齐)时强制转换的16位值? 最终目标是16位缓冲区,它将被强制转换为16位对齐方式。 可以吗
8位值-据我所知,使用下面的代码应该可以。 但是在编码方面有什么建议吗?
编辑1。
NvM_SrcPtr
指针参数被传递类似这样的东西。
INT8U Byte = 0x00U;
INT16U Word = 0x0000U;
NvM_WriteBlock(SPECIAL_MODE_TYPE_VAL, &Byte);
NvM_WriteBlock(SPECIAL_MODE_TYPE_VAL, (INT8U*)&Word);
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
unsigned __int8 GX=7;
printf("Value:%d\n",GX);
printf("%d\n",&GX);
for(i=0;i<8;i++){
printf("Bin:%d\n",GX&0b1<<i);
}
/*Pass INT8U to INT16U */
unsigned __int16 *DDC;
DDC=(unsigned __int16*)&GX;
printf("Value:%d\n",*DDC);
printf("%d\n",DDC);
/*Clearly Address is same but printf may be diff*/
for(i=0;i<8;i++){
printf("Bin:%d\n",(*DDC)&0b1<<i);
}
for(i=8;i<16;i++){
printf("Bin2:%d\n",(*DDC)&0b1<<i);
}
/*First 8 bit same*/
/*other 8 bit not sure because another 8bit give by address is not legal because not alloc*/
/*you can trans 8bit to 16bit using address if you dont fix another 8bit*/
/*if you want cover another value please make another 8bit stay original value*/
/*like below*/
unsigned __int16 NewValue=80;
*DDC=(*DDC)&(0xff00|NewValue);
/*By the way in multithreading case dont use this method because memory use will be too complex*/
return 0;
}
一般规则是,只能使用正确的类型取消引用指针。 您可以将指针转换为其他类型,但是如果要取消引用它,则需要将其转换回原始类型。
这些指针转换是实现定义的 。 这意味着不同的指针在某些系统上可能具有不同的表示形式,因此您应该阅读编译器手册,以了解它们如何在系统上工作。 在典型的现代系统上,指针通常使用相同的表示形式,并且指针转换才起作用。
但是,您的情况可能特殊。 您会看到字符类型指针是C标准中的一个特殊例外:保证它们具有可转换为其他指针类型的表示形式,并且即使它们是从其他指针类型派生的,也可以始终取消引用它们。 因此,如果INT8U
是unsigned char
(很有可能),则指针转换就可以了。
没有转换的8位就可以了:
INT8U Byte = 0x00U;
INT8U *NvM_SrcPtr = &Byte; // ok - matching type
INT8U *src = NvM_SrcPtr; // ok - matching type
*dst = (INT16U)(*src); // ok - dereference with original type
具有转换的16位最有可能:
INT16U Word = 0x0000U;
INT8U *NvM_SrcPtr = &Word; // impl.def or special case
INT16U *src = (INT16U*)NvM_SrcPtr; // impl.def or special case
*dst = *src; // ok - dereference with original type
16位-> 8位最有可能:
INT16U Word = 0x0000U;
INT8U *NvM_SrcPtr = &Word; // impl.def or special case
INT8U *src = NvM_SrcPtr; // ok - matching type
*dst = (INT16U)(*src); // ok if INT8U is unsigned char
8位-> 16位不适合:
INT8U Byte = 0x00U;
INT8U *NvM_SrcPtr = &Byte; // ok - matching type
INT16U *src = (INT16U*)NvM_SrcPtr; // impl.def
*dst = *src; // invalid - derefence with invalid type
至于指针对齐,这是您需要注意的事情。 如果将指针转换为其他类型,然后将其未对齐,然后再转换回,则可能具有未定义的行为 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.