以下编译:
static int foo() { return 1; }
int foo();
Run Code Online (Sandbox Code Playgroud)
但是,它会一直编译吗?这种情况下的行为是否定义得很好?当非静态原型遵循静态声明时,它意味着什么?
一个可以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编译器对此进行了测试,它没有抱怨.
这个片段编译成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++ 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) 我正在搜索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文件中.
这是我的想法:
为什么extern "C"(通常用于C接口)将C++类分组?这种用法对某些东西有用吗?
即使type0,type1并type2出现了,自己的头在这里没有包括在内,但在cpp文件(如sample.h).当我调用类的Sample,但是,我必须包括这些报头(例如type0.h,type1.h,type2.h),这似乎很不方便.
想象一下,我们有一个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++中,将函数或变量放在匿名命名空间中会使其内部链接,即与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) 还有一个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文件被包含两次,并且因为声明了 …
在阅读了很多关于静态变量初始化的问题之后,我仍然不确定它如何适用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++开发一个动态库,由用IDL(交互式数据语言)编写的现有程序调用.我知道我需要使用extern"C"来禁用名称修改,以便IDL可以调用它需要的函数(其余的调用机制非常简单).
但是,我总是对使用我不完全理解的语言的功能犹豫不决,所以我的问题是:如果有的话,我会通过恢复到C链接而丢失C++的哪些功能?我认为命名空间是一个显而易见的,但它是否完全禁用了C++的所有其他优点?我还可以使用C++ STL,以及我所依赖的所有各种语言功能(特别是C++ 11)吗?还是我坚持用C编码?