在qsort中解释C代码行

时间:2017-12-01 23:54:11

标签: c syntax qsort

我一直在研究qsort的不同实现,并且在这里找到的源代码中有一行(https://code.woboq.org/userspace/glibc/stdlib/qsort.c.html),我不明白。它看起来像一个函数指针声明。我很感激任何帮助。我已经根据需要包含了尽可能多的代码(注意到这一行),我想回答这个问题。如果没有,请告诉我,谢谢。

typedef struct
{
    char *lo;
    char *hi;

} stack_node;


void _quicksort (void *const pbase, size_t total_elems, size_t size, cmp_t cmp, void *arg)
{

    char *base_ptr = (char *) pbase;

    const size_t max_thresh = 4 * size;

    if (total_elems == 0)

        return;

    if (total_elems > 4)
    {
        char *lo = base_ptr;
        char *hi = &lo[size * (total_elems - 1)];
        stack_node stack[(8 * sizeof(size_t))];
        stack_node *top = stack;

        /* Line below is a function pointer declaration?  Initializes struct? */

        ((void) ((top->lo = (((void*)0))), (top->hi = (((void*)0))), ++top));

        while ((stack < top))
        {
            char *left_ptr;
            char *right_ptr;

            char *mid = lo + size * ((hi - lo) / size >> 1);

...代码继续

2 个答案:

答案 0 :(得分:7)

不,它不是函数指针声明。这只是一种令人费解的方式

top->lo = 0;
top->hi = 0;
++top;

您可以使用,运算符

将上述内容重写为单个表达式语句
top->lo = 0, top->hi = 0, ++top;

然后添加不必要的演员

top->lo = (void *) 0, top->hi = (void *) 0, ++top;

和一堆冗余的() s

(top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top;

然后将整个内容转换为(void)(例如,禁止任何潜在的编译器警告表达式结果&#34;未使用&#34;)

((void) ((top->lo = (((void *) 0))), (top->hi = (((void *) 0))), ++top));

现在你有原始版本。

为什么有人决定在,运算符中使用这种奇怪的语法,而且大量的冗余()对我来说并不清楚。看起来像一个宏扩展。也许它是一块已经预处理过的代码? ((void *) 0)部分可能很容易成为标准NULL宏的预处理器替换。

答案 1 :(得分:2)

查看URL我们发现该行实际上是一个宏定义

/* The next 4 #defines implement a very fast in-line stack abstraction. */
/* The stack needs log (total_elements) entries (we could even subtract
   log(MAX_THRESH)).  Since total_elements has type size_t, we get as
   upper bound for log (total_elements):
   bits per byte (CHAR_BIT) * sizeof(size_t).  */

#define STACK_SIZE        (CHAR_BIT * sizeof(size_t))
#define PUSH(low, high)   ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
#define POP(low, high)    ((void) (--top, (low = top->lo), (high = top->hi)))
#define STACK_NOT_EMPTY   (stack < top)

,代码实际显示在PUSH的定义中,其简编出现在POP中。额外() s的使用是为了确保++top--top以正确的顺序发生inline

当我们在qsort.c顶部看到 Copyright(C)1991 - 2017 消息时,以这种方式实现它的原因更清楚...... 1991年的编译器可能真的很糟糕在内联函数中。