값이 0 크기 어레이를 생성하는지 테스트할 수 있는 C 전처리기 #이(가)의 방법이 필요함
나는 임베디드 프로젝트에 완벽하게 맞도록 64K까지 패딩해서 플래시 블록을 채워야 하는 구조를 가지고 있다.그래서 다음과 같은 것이 있다.#define
다음을 사용하여 구조물의 요소를 더하는sizeof()
그리고 얼마나 큰지 결정한다.pad[]
마지막에는 전체 크기가 64K가 되도록 해야 한다.
예:
#define SIZE_OF_MY_PAD (0x10000 - (sizeof(uint16_t) + sizeof(uint8_t)*32 + ... ))
typedef struct {
uint16_t firstElement;
uint8_t secondElementArray[32];
...
uint8_t pad[SIZE_OF_MY_PAD];
};
이것은 오랜 시간 동안 훌륭하게 작동해 왔으며, 우리가 갑자기 어떤 빌드 구성에서 패드가 전혀 필요하지 않게 되었다.왜냐하면 그것은 정확히 64k이기 때문이다 이미.이것은 우리의 컴파일러 (GCC가 아닌)가 허용하지 않기 때문에 코드를 실패하게 한다.pad[0]
.
나는 내가 사용할 수 있는 전처리기적 가치를 만들기 위해 다양한 방법을 시도했다.#if
문장 이것이 감지되었을 때, 그러나 항상 실패한다 왜냐하면,sizeof()
에 합법적이다#define
, 그것은 합법적이지 않다.#if
.
이 문제는 C11에 소개된 익명의 구조물의 도움으로 전처리가 필요 없이 해결될 수 있다.
플래시 유형을 익명 구조물에 포함된 구성원을 포함하는 조합으로 정의하십시오.만들다char _pad[0x10000]
도입형의 총체적 규모를 강제하는 조합의 다른 조합원
typedef union {
struct {
uint16_t firstElement;
uint8_t secondElementArray[32];
float thirdElement;
};
char _pad[0x10000];
} flash_t;
이 솔루션은 구조 부재 레이아웃의 어떤 수정에도 견고하다.더욱이, 이는 기술적으로 금지된 (GCC에서 허용되지만) C 표준에서 금지된 제로 길이 배열을 정의하는 문제를 피할 수 있다.또한, 플래시의 최대 크기가 오버플로되었는지 확인하기 위해 정적 주장을 추가할 수 있다.
예제 프로그램:
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
typedef union {
struct {
uint16_t firstElement;
uint8_t secondElementArray[32];
float thirdElement;
// int kaboom[20000]; // will trigger assert if uncommented
};
char _pad[0x10000];
} flash_t;
_Static_assert(sizeof(flash_t) == 0x10000, "Oops, flash_t got too large");
int main() {
flash_t flash;
printf("offsetof(flash.firstElement) = %zi\n", offsetof(flash_t, firstElement));
printf("offsetof(flash.secondElementArray) = %zi\n", offsetof(flash_t, secondElementArray));
printf("offsetof(flash.thirdElement) = %zi\n", offsetof(flash_t, thirdElement));
printf("sizeof(flash) = %zi\n", sizeof flash);
return 0;
}
예상 출력 생성:
offsetof(flash.firstElement) = 0
offsetof(flash.secondElementArray) = 2
offsetof(flash.thirdElement) = 36
sizeof(flash) = 65536
편집
코멘트에 제시된 바와 같이 조합원은
_pad
로 이름이 바뀔 수 있음_rawData
의 의미 때문에._pad
다르다pad
그 문제에서회원이면
pad
그 유형 내에 익명 구조물의 끝에 유연한 구성원으로 추가할 수 있다.
typedef union { struct { ...; uint8_t pad[]; }; char _rawData[0x10000]; } flash_t;
'programing' 카테고리의 다른 글
Vue js 라우터: 클릭 이벤트에서 URL 쿼리를 변경하거나 업데이트하는 방법 (0) | 2022.05.14 |
---|---|
vuex 스토어 보기 (0) | 2022.05.14 |
vue.js 2에서 계산된 것과 탑재된 것의 주요 차이점은 무엇인가? (0) | 2022.05.14 |
뷰에티파이 아이콘이 올바르게 표시되지 않음: "$vuetify.icons...." (0) | 2022.05.14 |
무엇이 더 효율적인가?가루를 이용해 네모나게 만들거나, 아니면 그냥 곱해서 만들거나? (0) | 2022.05.14 |