连接与指向函数的指针

  在一个程序里混用C和C++代码片段时,我们有时会希望把一个语言里定义的函数指针传递到另一个语言中定义的函数里。如果两个语言的两个实现共享同样的连接约定和函数调用机制,这种将指针传递给函数的工作将简单。但是,一般说没办法去假定这种共性。因此,为了保证一个函数的调用能够符合它被假定的调用方式,我们就必须当心。

  在为一个声明刻画连接约定时,这个特殊约定将应用于由此声明(声明组)引进的所有函数类型、函数名和变量名。这样就可以做出各种奇怪的---有时也是必不可少的---连接可能性的组合。例如,

    typedef int (*FT)(const void*, const void*);            // FT具有C++连接

    extern "C" {
        typedef int (*CFT)(const void*, const void*);       // CFT具有C连接
        void qsort(void* p, size_t n, size_t sz, CFT cmp);  // cmp具有C连接
    }

    void isort(void* p, size_t n, size_t sz, FT cmp);        // cmp具有C++连接
    void xsort(void* p, size_t n, size_t sz, CFT cmp);       // cmp具有C连接
    extern "C" void ysort(void* p, size_t n, size_t sz, FT cmp);// cmp具有C++连接

    int compare(const void*, const void*);            // compare()具有C++连接
    extern "C" int ccmp(const void*, const void*);    // ccmp()具有C连接

    void f(char* v, int sz)
    {
        qsort(v, sz, 1, &compare);        // 错误❌
        qsort(v, sz, 1, &ccmp);           // ok✅

        isort(v, sz, 1, &compare);        // ok✅
        isort(v, sz, 1, &ccmp);           // 错误❌
    }

如果一个实现中的C和C++连接采用同样的调用约定,它就可以接受上面的错误情况,作为对语言的一种扩充。

🔚