[c] 가장 좋아하는 C 프로그래밍 트릭은 무엇입니까? [닫은]

예를 들어, 나는 최근 리눅스 커널에서 이것을 발견했다.

/ * 조건이 true 인 경우 컴파일 오류를 발생시킵니다 * /
#define BUILD_BUG_ON (condition) ((void) sizeof (char [1-2 * !! (condition)]))

따라서 코드에서 8 바이트 크기의 배수와 같은 구조가있는 경우 하드웨어 제약 때문에 아마도 다음을 수행 할 수 있습니다.

BUILD_BUG_ON (((sizeof (struct mystruct) % 8)! = 0);

struct mystruct의 크기가 8의 배수가 아닌 한 컴파일되지 않으며 8의 배수이면 런타임 코드가 전혀 생성되지 않습니다.

내가 아는 또 다른 속임수는 “Graphics Gems”라는 책에서 한 헤더 파일이 한 모듈에서 변수를 선언하고 초기화하는 동안 해당 모듈을 사용하는 다른 모듈에서는 externs로 선언하는 것입니다.

#ifdef DEFINE_MYHEADER_GLOBALS
#define GLOBAL
INIT (x, y) 정의 (x) = (y)
#그밖에
#define GLOBAL extern
INIT 정의 (x, y)
#endif

GLOBAL int INIT (x, 0);
GLOBAL int somefunc (int a, int b);

이를 통해 x와 somefunc를 정의하는 코드는 다음을 수행합니다.

#DEFINE_MYHEADER_GLOBALS 정의
#include "the_above_header_file.h"

x와 somefunc ()를 사용하는 코드는 다음과 같습니다.

#include "the_above_header_file.h"

따라서 필요한 전역 및 함수 프로토 타입 인스턴스와 해당 extern 선언을 모두 선언하는 하나의 헤더 파일을 얻습니다.

그렇다면 그 라인에서 가장 좋아하는 C 프로그래밍 트릭은 무엇입니까?



답변

C99는 익명 배열을 사용하여 정말 멋진 것들을 제공합니다.

무의미한 변수 제거

{
    int yes=1;
    setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
}

된다

setsockopt(yourSocket, SOL_SOCKET, SO_REUSEADDR, (int[]){1}, sizeof(int));

가변 인수 인수 전달

void func(type* values) {
    while(*values) {
        x = *values++;
        /* do whatever with x */
    }
}

func((type[]){val1,val2,val3,val4,0});

정적 링크리스트

int main() {
    struct llist { int a; struct llist* next;};
    #define cons(x,y) (struct llist[]){{x,y}}
    struct llist *list=cons(1, cons(2, cons(3, cons(4, NULL))));
    struct llist *p = list;
    while(p != 0) {
        printf("%d\n", p->a);
        p = p->next;
    }
}

내가 생각하지 못한 다른 멋진 기술이 많이 있다고 확신합니다.


답변

Quake 2 소스 코드를 읽는 동안 나는 다음과 같은 것을 생각해 냈습니다.

double normals[][] = {
  #include "normals.txt"
};

(더 많거나 적은, 지금 확인하기 편리한 코드가 없습니다).

그 이후로, 전 처리기의 창조적 인 사용의 새로운 세계가 내 눈앞에서 열렸다. 더 이상 헤더 만 포함하지 않지만 이제는 코드 전체를 사용하고 재사용 성을 크게 향상시킵니다. :-p

존 카맥 감사합니다! xD


답변

= {0};memset을 호출하지 않고도 구조를 초기화 하는 것을 좋아 합니다.

struct something X = {0};

이것은 구조체 (또는 배열)의 모든 멤버를 0으로 초기화합니다 (그러나 패딩 바이트는 아님)-0으로 설정 해야하는 경우 memset을 사용하십시오).

그러나 동적으로 할당 된 대규모 구조에는 이와 관련하여 몇 가지 문제 가 있음을 알고 있어야합니다 .


답변

우리가 C 트릭에 대해 이야기한다면, 내가 가장 좋아하는 것은 루프 언 롤링을위한 Duff의 장치 여야합니다 ! 나는 실제로 분노에서 그것을 사용할 수있는 올바른 기회를 기다리고 있습니다 …


답변

사용 __FILE____LINE__디버깅

#define WHERE fprintf(stderr,"[LOG]%s:%d\n",__FILE__,__LINE__);


답변

C99에서

typedef struct{
    int value;
    int otherValue;
} s;

s test = {.value = 15, .otherValue = 16};

/* or */
int a[100] = {1,2,[50]=3,4,5,[23]=6,7};


답변

일단 내 친구와 나는 다시 정의하기가 까다로운 스택 손상 버그를 발견했습니다.

다음과 같은 것 :

#define return DoSomeStackCheckStuff, return