相关疑难解决方法(0)

拒绝指针的数组大小的宏

经常教授的标准数组大小的宏是

#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
Run Code Online (Sandbox Code Playgroud)

或一些等效的形成.然而,当传入指针时,这种事情会默默地成功,并且在运行时看起来似乎有道理,直到事情神秘地分崩离析.

犯这个错误太容易了:一个具有局部数组变量的函数被重构,将一些数组操作移动到一个以数组作为参数调用的新函数中.

所以,问题是:是否有一个"卫生"宏来检测ARRAYSIZEC中宏的滥用,最好是在编译时?在C++中,我们只使用专门用于数组参数的模板; 在C中,似乎我们需要一些方法来区分数组和指针.(例如,如果我想拒绝数组,我只是(arr=arr, ...)因为数组赋值是非法的).

c arrays macros c-preprocessor

49
推荐指数
4
解决办法
1万
查看次数

在确定数组的大小时,括号会有所作为吗?

以下程序在gcc 4.8.2上两次打印相同的数字:

#include <stdio.h>

int main()
{
    char a[13];
    printf("sizeof a  is %zu\n", sizeof a );
    printf("sizeof(a) is %zu\n", sizeof(a));
}
Run Code Online (Sandbox Code Playgroud)

根据这篇reddit帖子,gcc在这方面并不符合标准,因为当数组到指针衰减没有发生时,括号表达式不在异常列表中.

这家伙是对的吗?这是相关的标准报价:

除非它是运算sizeof符或一元运算&符的操作数,或者是用于初始化字符数组数组的字符串文字,或者是用于初始化与元素类型兼容的数组的宽字符串文字,否则具有wchar_t的左值类型'array of type'被转换为一个表达式,其类型为'指向类型的指针',指向数组对象的初始成员而不是左值.

为了清楚起见,他认为(a)应该触发数组到指针的衰减,因为上面的列表中没有括号括起来(sizeof运算符,一元运算&符,字符串文字作为初始值).

c arrays sizeof parentheses language-lawyer

26
推荐指数
2
解决办法
993
查看次数

是否有一种类型安全的方法来获取C中的数组元素?

在C中获取数组元素的通常方法是这样的:

#define COUNTOF(arr) (sizeof(arr) / sizeof(arr[0]))
Run Code Online (Sandbox Code Playgroud)

这导致了一个整数常量表达式,这也是一个非常好的加法.

问题是它不是类型安全的:int* i; COUNTOF(i); /* compiles :( */.在实践中,这应该很少出现,但为了正确起见,使这种类型安全是很好的.


在C++ 03中这很容易(在C++ 11中它更容易,留给读者练习):

template <typename T, std::size_t N>
char (&countof_detail(T (&)[N]))[N]; // not defined

#define COUNTOF(arr) (sizeof(countof_detail(arr)))
Run Code Online (Sandbox Code Playgroud)

这使用模板推导来获取N数组的大小,然后将其编码为类型的大小.

但是在C中我们没有得到那种语言功能.这是我做的小框架:

// if `condition` evaluates to 0, fails to compile; otherwise results in `value`
#define STATIC_ASSERT_EXPR(condition, value) \
        (sizeof(char[(condition) ? 1 : -1]), (value))

// usual type-unsafe method
#define COUNTOF_DETAIL(arr) (sizeof(arr) / sizeof(arr[0]))

// new method:
#define COUNTOF(arr)                            \
        STATIC_ASSERT_EXPR(/* ??? */,           \
                           COUNTOF_DETAIL(arr)) …
Run Code Online (Sandbox Code Playgroud)

c arrays c89 visual-c++

5
推荐指数
1
解决办法
389
查看次数

C宏的创造性/有趣用途; metaprograming

我一直在寻找有趣且优选有用的C宏/定义示例,它们比定义consts或min/max函数更广泛.我的理解是,宏应该允许某种程度的元编程(尽管我并不完全确定),但是搜索未能揭示太多,因此非常感谢使用宏进行元编程的示例,或解释为什么它不能工作.总的来说,我对任何"酷"的宏用途感兴趣.

PS我明白这个问题很快就会"没有建设性和关闭性",但我认为它至少可以成为一个有趣的社区维基问题.

编辑:我对C++,任何东西都不感兴趣.

c macros metaprogramming c-preprocessor

3
推荐指数
1
解决办法
437
查看次数

数组长度使用指针

可以使用*(&arr+1)-arr该数据计算数组长度,然后简化(&arr)[1]-arr进一步简化为的数组长度1[&arr]-arr.

但是,当在与已完成内存分配的函数中计算长度时,计算错误的结果.

例如,

#include <iostream> 
#define ARRAY_SIZE(arr) (1[&arr]-arr)      
using namespace std;

void func(int *arr)
{
    cout<<ARRAY_SIZE(arr)<<endl;
}

int main()
{
    int arr[]={1,2,3,4,5};
    cout<<ARRAY_SIZE(arr)<<endl;
    func(arr);
}
Run Code Online (Sandbox Code Playgroud)

这给出了输出:

5
8
Run Code Online (Sandbox Code Playgroud)

是什么导致了这种奇怪的行为?

c++ arrays pointers pass-by-reference

3
推荐指数
1
解决办法
200
查看次数