code

C에서 변수 이름을 얻는 프로그래밍 방식?

starcafe 2023. 6. 7. 23:02
반응형

C에서 변수 이름을 얻는 프로그래밍 방식?

변수에서 데이터를 덤프하는 도구를 개발하고 있습니다.변수 이름과 값을 덤프해야 합니다.

내 솔루션:변수 이름을 문자열로 저장하고 "변수 이름"을 인쇄한 다음 값을 인쇄합니다.

변수 이름을 알 수 있는 프로그래밍 방식이 있습니까?

다음과 같은 방법을 사용할 수 있습니다.

#define DUMP(varname) fprintf(stderr, "%s = %x", #varname, varname);

제가 C를 처음 사용했을 때 제가 쓴 이 헤더는 유용한 아이디어를 포함하고 있을 수도 있습니다.예를 들어 C 값을 인쇄하고 형식 지정자를 하나로 제공할 수 있습니다(일부 추가 정보도 제공).

#define TRACE(fmt, var) \
        (error_at_line(0, 0, __FILE__, __LINE__, "%s : " fmt, #var, var))

C++을 사용하는 경우 전달된 값의 유형을 사용하여 적절하게 출력할 수 있습니다.이 경우 변수 값을 "예쁘게 인쇄"하는 방법에 대해 훨씬 더 유리한 예를 제공할 수 있습니다.

C에서 변수 이름은 컴파일 단계(및 변수가 전역인 경우 링크 단계) 동안 존재하지만 런타임에는 사용할 수 없습니다.변수 이름을 나타내는 리터럴 문자열이 포함된 솔루션을 선택해야 합니다.

단축 방법:

#define GET_VARIABLE_NAME(Variable) (#Variable)

테스트:

#include <string>
class MyClass {};


int main(int argc, char* argv[]) {
    int foo = 0;

    std::string var_name1 = GET_VARIABLE_NAME(foo);
     char* var_name2 = GET_VARIABLE_NAME(foo);
     char* var_name3 = GET_VARIABLE_NAME(MyClass);


    return 0;
}

당신이 원하는 것을 할 수 있는 코드가 있습니다.사전 처리기를 사용하여 변수 이름을 인쇄할 수 있도록 문자열화합니다.변수 이름과 값(유형 기반) 및 해당 변수의 메모리 레이아웃을 모두 덤프합니다.다음 프로그램은 수행 방법을 보여 줍니다.

#include <stdio.h>
#include <stdlib.h>

static void dumpMem (unsigned char *p, unsigned int s) {
    int i;
    unsigned char c[0x10];
    printf (">>      ");
    for (i = 0; i < 0x10; i++) printf (" +%x",i);
    printf (" +");
    for (i = 0; i < 0x10; i++) printf ("%x",i);
    printf ("\n");
    for (i = 0; i < ((s + 15) & 0xfff0); i++) {
        if ((i % 0x10) == 0) {
            if (i != 0) printf ("  %*.*s\n", 0x10, 0x10, c);
            printf (">> %04x ",i);
        }
        if (i < s) {
            printf (" %02x", p[i]);
            c[i & 0xf] = ((p[i] < 0x20) || (p[i] > 0x7e)) ? '.' : p[i];
        } else {
            printf ("   ");
            c[i & 0xf] = ' ';
        }
    }
    printf ("  %*.*s\n", 0x10, 0x10, c);
}
#define DUMPINT(x) do{printf("%s: %d\n",#x,x);dumpMem((char*)(&x),sizeof(int));}while(0)
#define DUMPSTR(x) do{printf("%s: %s\n",#x,x);dumpMem(x,strlen(x));}while(0)
#define DUMPMEM(x,s) do{printf("%s:\n",#x);dumpMem((char*)(&x),s);}while(0)

typedef struct {
    char c;
    int i;
    char c2[6];
} tStruct;

int main (void) {
    int i = 42;
    char *s = "Hello there, my name is Pax!";
    tStruct z;
    z.c = 'a'; z.i = 42; strcpy (z.c2,"Hello");

    DUMPINT (i);
    DUMPSTR (s);
    DUMPMEM (z,sizeof(z));

    return 0;
}

다음 출력은 다음과 같습니다.

i: 42
>>       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
>> 0000  2a 00 00 00                                      *...
s: Hello there, my name is Pax!
>>       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
>> 0000  48 65 6c 6c 6f 20 74 68 65 72 65 2c 20 6d 79 20  Hello there, my
>> 0010  6e 61 6d 65 20 69 73 20 50 61 78 21              name is Pax!
z:
>>       +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f +0123456789abcdef
>> 0000  61 b6 16 61 2a 00 00 00 48 65 6c 6c 6f 00 0d 61  a..a*...Hello..a

그고리의 상태에 약당제아이궁닌면다금하지정신이신만▁and면다궁하금,,아.do {...} while (0)매크로에서, 그것은 당신이 그것을 둘러싸는 충분한 가새가 있는지 걱정할 필요 없이 그것을 코드의 어느 곳에나 배치할 수 있도록 하는 것입니다.

임의 변수에 대해 이 작업을 수행해야 하는 경우 컴파일러 또는 플랫폼에서 제공하는 디버거 API(Windows의 DbgHelp)를 사용해야 합니다.

제가 작업한 일부 임베디드 시스템에서는 사전에 알려진 특정 중요 변수의 값을 명령 시 표시할 수 있어야 했고, 이를 위해 필요한 것은 간단한 이름/포인트 테이블뿐이었습니다.

typedef 
struct vartab {
    char const* name;
    int * var;
} vartab;


vartab varTable[] = {
    { "foo", &foo },
    { "bar", &bar }
};

그런 다음 테이블에서 해당 변수 이름을 검색하고 포인터가 가리키는 이름과 데이터를 덤프하는 작은 루틴을 사용했습니다.를 "int" "int" "printf" "라는 식으로 변경할 수 있습니다.void*그리고 그 쓰레기들을 건네줍니다.snprintf()데이터를 포맷할 수도 있습니다.

때로는 테이블을 작성하는 데 도움이 되는 매크로를 사용하기도 합니다(변수를 선언하기도 함).하지만 솔직히 말해서, 저는 그것이 이해를 더 복잡하게 만들 뿐이라고 생각합니다(특히 프로젝트에 새로 합류한 사람에게는 종종 작은 "WTF?" 순간이 있습니다). 그리고 실제로는 일을 많이 단순화하지 않습니다.

사람들은 종종 프로그램이 자기 성찰(또는 현재 전문 용어로 "반성")하기를 원합니다.그러나 대부분의 프로그래밍 언어는 프로그램의 모든 세부 사항(변수 이름, 함수 이름, 유형, 표현 구조 등)을 반영할 수 있는 기능이 거의 없거나(예: Java) 없음(C) 기능을 제공하지 않습니다.

모든 언어에 대해 이렇게 할 수 있는 방법이 있습니다. 언어 밖으로 나가서 언어에서 정보를 추출하도록 설계된 도구를 사용합니다.이를 수행할 수 있는 도구 클래스를 프로그램 변환 시스템이라고 합니다.

프로그램 변환 시스템을 사용하여 "변수 이름 가져오기" 및 값을 인쇄하는 방법에 대한 자세한 내용은 다음 SO 답변을 참조하십시오.변수에 대한 변경 내용 자동 추적

이거 먹어봐요.

#define MACRO_VARIABLE_TO_STRING(Variable) ((void) Variable,#Variable)

코드(보이드) 변수는 void 변환으로, no-op이며 쉼표 연산자와 매크로 문자열화가 있습니다.따라서 컴파일러 체크가 변수인 변수 이름을 포함하는 net result는 constchar*입니다.

이제 변수의 이름을 알고 printf()를 사용하여 값을 인쇄할 수 있습니다.

@Matt Joiner의 매우 정확한 대답에도 불구하고, 는 #define 매크로를 사용하는 것이 얼마나 간단한지 보기 위해 이것을 예시하는 완전한 짧은 코드를 쓰고 싶습니다.

#include <stdio.h>
#define val_name(v)#v
int main()
    {
    char a[]="hello";
    printf("%s %s",a,val_name(a));
    }

출력: 안녕하세요 a

실행 파일이 디버깅 정보로 컴파일된 경우 이 정보를 얻을 수 있습니다.그렇지 않다면, 당신은 아마 운이 없을 것입니다.그래서 디버거를 만들고 있는 건가요? 왜죠? 기존의 관리용 디버거는 매우 성숙합니다.휠을 다시 발명하는 대신 기존 공구를 사용하는 것이 어떻습니까?

유감스럽게도 당신의 프로그램 내부에서 그렇게 하는 좋은 방법은 없습니다. (아나크로릭스의 답변을 제외하고).저는 당신의 문제에 대한 올바른 해결책이 디버거 스크립트라고 생각합니다.대부분의 디버거에서는 디버거가 프로그램 실행을 중단할 때마다 실행되도록 연결할 수도 있습니다.^C프로그램과 상호 작용할 때마다 프로그램 상태에 대한 스냅샷을 얻습니다.

언급URL : https://stackoverflow.com/questions/1623111/programmatic-way-to-get-variable-name-in-c

반응형