programing

값이 0 크기 어레이를 생성하는지 테스트할 수 있는 C 전처리기 #이(가)의 방법이 필요함

prostudy 2022. 5. 14. 22:27
반응형

값이 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;

참조URL: https://stackoverflow.com/questions/66992575/i-need-a-way-in-a-c-preprocessor-if-to-test-if-a-value-will-create-a-0-size-arr

반응형