获取运算符sizeof来区分简单地址,指针和数组(可能带有宏?)

问题描述 投票:1回答:1

我想将其第一个参数的“正确”大小作为第二个参数传递给函数mem,这是一个无效的地址。

我想到使用宏MEM,该宏使用运算符sizeof。该宏应该在预处理时通过查看文本来“推断”“正确”的大小,即,第一个参数如何用代码编写。

除了我的宏,当参数是使用数组名称(arr)传递的数组时,它不能很好地工作。 (请注意,如果我按照注释中的建议通过&arr,则宏可以很好地工作)

#include <stdio.h>

#define MEM(addr) mem(addr,sizeof *addr) // <-- does not work for arrays

void mem(const void* , int );

int main()
{
    int t=3;;
    int arr[10];
    int* p=&t;

    MEM(&t); // --> mem(&t,sizeof *&t)   <- OK!
    MEM(p); // --> mem(p,sizeof *p   <- OK! 

    MEM(arr); // --> mem(arr,sizeof *arr)  <- NO! I WANT THE SIZE OF THE ALL ARRAY!
           // SO I WANT --> mem(arr,sizeof arr)
    return 0;
}

void mem(const void* pp, int bytestoread) // prints bytestoread bytes starting from address pp
{
    int i;
    unsigned char* p=(unsigned char*)pp;
    for(i=0;i<bytestoread;i++)
    {
        if(i%8==0)
        {
            if(i!=0) printf("\n");
            printf("%p: ",p);
        }
        printf("%02x ",*p);
        p++;
    }
    printf("\n\n");
}

如果对我的问题有其他解决方案或方法,则可以使用宏,甚至更好。但是数组作为参数传递给函数时会衰减,因此我看不到如何使用函数来完成所需的操作。

即使对C预处理程序有一些改动,例如在代码中写入的地址名称上使用字符串化预处理程序运算符#并相应地有选择地编译MEM,我也很高兴,但是我无法做到这一点。 (也许也使用#if #else #endif预处理程序指令...?)

跟进

以下将是一个试探性的解决方案,它利用了以下事实:对于数组arr(与常规指针相反)&arr ==arr...

#define SIZE(add) (  #add[0]=='&' ? 
                     sizeof *add : 
                     ((void*)add==(void*)&add ? sizeof add : sizeof *add)  )

#define MEM(address) mem( address, SIZE(address) )

......但是,当在代码中将address写为&t时(例如,tint),这当然不会编译,因为&&t不是在语法上正确,即使检查#add[0]=='&'确保不会执行它。

1)是否有使其工作的方法?2)还是应该编写一个解析器,该解析器根据传递给解析器的文本输出要编译的代码?3)对于在#if指令中可以用作条件的条件,C预处理器为何如此严格? (我什至不能使用字符串文字或#运算符!只允许使用const表达式,例如2> 1或其他定义的宏)]

c pointers macros sizeof preprocessor
1个回答
0
投票

MEM宏似乎没有明显的解决方案,尽管可能存在带有预处理器条件表达式的解决方案,其中根据操作数的类型,我们决定如何计算大小。

C中的常见做法是创建带有额外参数的函数,该参数占用数据容器的大小。因此,您将编写这样的内容,而根本不使用宏:

int t = 3;
int arr[10] = {0};
int *p = &t;

mem(&t, sizeof(t)); 
mem(p, sizeof(*p));
mem(arr, sizeof(arr) / sizeof(arr[0])); // <- 40/4 = 10

这非常冗长,但在这种情况下,您可以依靠此并确保获得预期的行为。

© www.soinside.com 2019 - 2024. All rights reserved.