标签: linkage

当非静态函数声明遵循静态函数声明时会发生什么?

以下编译:

static int foo() { return 1; }
int foo();
Run Code Online (Sandbox Code Playgroud)

但是,它会一直编译吗?这种情况下的行为是否定义得很好?当非静态原型遵循静态声明时,它意味着什么?

c static function linkage

17
推荐指数
1
解决办法
1281
查看次数

通过extern"C"函数与C++对象的接口

一个可以extern "C"函数接受或返回C++ -特定的数据类型,如参考文献,指针到成员或非POD类(由值)?我在C++标准中找不到禁止此内容的任何内容.从逻辑上讲,我希望标准可以说一些,因为C ABI不一定适合传递这类类型.

我想要使​​用C链接的原因与C编译器无关.该函数仅从C++代码调用.我只想从动态库中导出未编码的函数名.

一个愚蠢的代码示例:

class Foo {
  public:
    virtual void doit() = 0;
};

class Bar : public Foo {
  public:
    void doit() { std::cout << "Bar" << std::endl; }
};

extern "C" Foo& getFoo() { static Bar bar; return bar; }

extern "C" Bar getBar() { return Bar(); }
Run Code Online (Sandbox Code Playgroud)

这在Linux上用GCC编译,并按预期工作.应该是标准吗?

问题是对这个问题的评论中的讨论的后续行动.

更新我用Comeau编译器对此进行了测试,它没有抱怨.

c++ standards linkage

16
推荐指数
1
解决办法
2868
查看次数

GCC和clang之间的矛盾结果与C++标准中的[basic.link]/7有关

这个片段编译成clang,

namespace A {
    void f() {
        void g();
        g();
    }
}

void A::g() { }
Run Code Online (Sandbox Code Playgroud)

但GCC只接受代码,如果g在命名空间内定义A如下:

namespace A {
    void f() {
        void g();
        g();
    }
    void g() {}
}
Run Code Online (Sandbox Code Playgroud)

但我相信[basic.link]/7中没有任何内容禁止上面的第一个片段.

c++ linkage language-lawyer c++11 c++14

16
推荐指数
1
解决办法
374
查看次数

constexpr和static constexpr全局变量之间的区别

在C++ 11标准中,在标题中定义时constexpr,static constexpr全局变量之间有什么区别?更具体地说,当多个翻译单元包含相同的标题时,哪个声明(如果有的话)可以保证在翻译单元中定义相同的变量?

例如,

cexpr.h:

#ifndef CEXPR_H
#define CEXPR_H

constexpr int cint = 1;
static constexpr int scint = 1;

#endif
Run Code Online (Sandbox Code Playgroud)

a.cpp:

#include "cexpr.h"
Run Code Online (Sandbox Code Playgroud)

b.cpp:

#include "cexpr.h"
Run Code Online (Sandbox Code Playgroud)

c++ linkage constexpr c++11

16
推荐指数
2
解决办法
4989
查看次数

为什么extern"C"组C++类(不是标题)在这里?

我正在搜索SVM库并遇到BudgetedSVM.

在源代码中,我发现了一个不寻常的用法,就像这样:

#sample.h

#ifndef SAMPLE_H
#define SAMPLE_H

//no header included or namespace declared here

#ifdef __cplusplus
extern "C" {
#endif

//no header included or namespace declared too

class Sample: public Parent
{
public:
    Sample();
    ~Sample();

    type0 fun(type1 val1, type2 val2);
    ...
};

#ifdef __cplusplus
}
#endif

#endif // SAMPLE_H
Run Code Online (Sandbox Code Playgroud)

如图所示,标头中不需要额外的头或命名空间,这些都在cpp文件中.

这是我的想法:

  1. 为什么extern "C"(通常用于C接口)将C++类分组?这种用法对某些东西有用吗?

  2. 即使type0,type1type2出现了,自己的头在这里没有包括在内,但在cpp文件(如sample.h).当我调用类的Sample,但是,我必须包括这些报头(例如type0.h,type1.h,type2.h),这似乎很不方便.

c++ linkage

15
推荐指数
1
解决办法
1968
查看次数

C++标准:命名空间范围的constexpr变量是否具有内部链接?

想象一下,我们有一个foo.h包含以下内容的标题:

#ifndef FOO_H_
#define FOO_H_

namespace foo {
constexpr std::string_view kSomeString = "blah";
}

#endif  // FOO_H_
Run Code Online (Sandbox Code Playgroud)

foo::kSomeString保证在任何翻译单元,包括内部联动foo.h?这在C++ 11和C++ 17之间有所不同吗?

在草案标准[basic.link]/3中

具有命名空间作用域的名称具有内部链接,如果它是非易失性const限定类型的非内联变量的名称,该变量既未显式声明为extern,也未声明为具有外部链接[...]

但我不知道是否constexpr算作"const-qualified".标准是否在某处说出来?

假设这保证具有内部链接,看起来ODR对此用法没有问题,对吧?(与此答案中的内容形成鲜明对比.)

c++ linkage language-lawyer c++11 c++17

15
推荐指数
1
解决办法
1514
查看次数

常规命名空间内匿名命名空间内符号的链接

在C++中,将函数或变量放在匿名命名空间中会使其内部链接,即与static在文件级别上声明它相同,但却是惯用的C++.

普通命名空间中的匿名命名空间怎么样?它仍然保证内部联系吗?

// foo.cpp

void func1() {
    // external linkage
}

static void func2() {
    // internal linkage
}

namespace {
    void func3() {
        // internal linkage
    }
}

namespace ns1 {
    void func4() {
        // external linkage
    }

    namespace {
        void func3() {
            // still internal linkage?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ namespaces anonymous linkage

14
推荐指数
3
解决办法
7238
查看次数

h文件中的静态关键字和内部链接

还有一个static问题.我看过以下内容:

我仍然无法理解以下行为:我有一个h文件:

// StaticTest.h
#include <stdio.h>

static int counter = 0;

struct A {
    A () {
        counter++;
        printf("In A's ctor(%d)\n", counter);
    }
    ~A () {
        counter--;
        printf("In A's dtor(%d)\n", counter);
    }
};

static A a;
Run Code Online (Sandbox Code Playgroud)

还有两个cpp文件:

// StaticTest1.cpp
#include "StaticTest.h"

int main () {
 return 0;
}
Run Code Online (Sandbox Code Playgroud)

和:

// StaticTest2.cpp
#include "StaticTest.h"
Run Code Online (Sandbox Code Playgroud)

该计划的输出是:

In A's ctor(1)
In A's ctor(2)
In A's dtor(1)
In A's dtor(0)
Run Code Online (Sandbox Code Playgroud)

现在,A构造函数被调用两次,因为h文件被包含两次,并且因为声明了 …

c++ static one-definition-rule linkage

14
推荐指数
1
解决办法
1066
查看次数

头文件中的const变量和静态初始化fiasco

在阅读了很多关于静态变量初始化的问题之后,我仍然不确定它如何适用const于命名空间级别的变量.

我在构建脚本生成的文件中有以下代码config.h:

static const std::string path1 = "/xyz/abc";
static const std::string path2 = "/etc";
Run Code Online (Sandbox Code Playgroud)

根据我所读到的,static关键字是没有必要的,甚至在这里弃用.

我的问题:上面的代码是否容易出现静态初始化惨败?

如果我在文件中有以下内容myclass.h:

class MyClass
{
public:
    MyClass(const std::string& str) : m_str(str) {}
    std::string Get() const { return m_str; }

private:
    std::string m_str;
}

const MyClass myclass1("test");
Run Code Online (Sandbox Code Playgroud)

这会引起静态初始化的任何问题吗?

如果我理解正确,由于const变量具有内部联系,两种情况都应该没有问题?

编辑:(由于运动答案)

也许我应该提一下,我对以下用例感兴趣:

main.cpp:

#include <config.h>
#include <myclass.h>

std::string anotherString(path1 + myclass1.Get());

int main()
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

关于这个用例的另一个问题:path2在这种情况下,编译器会优化吗?

c++ initialization linkage

14
推荐指数
3
解决办法
3万
查看次数

在C++中使用extern"C"时我到底输了什么?

我正在尝试用C++开发一个动态库,由用IDL(交互式数据语言)编写的现有程序调用.我知道我需要使用extern"C"来禁用名称修改,以便IDL可以调用它需要的函数(其余的调用机制非常简单).

但是,我总是对使用我不完全理解的语言的功能犹豫不决,所以我的问题是:如果有的话,我会通过恢复到C链接而丢失C++的哪些功能?我认为命名空间是一个显而易见的,但它是否完全禁用了C++的所有其他优点?我还可以使用C++ STL,以及我所依赖的所有各种语言功能(特别是C++ 11)吗?还是我坚持用C编码?

c c++ extern linkage

14
推荐指数
1
解决办法
1525
查看次数