假设代码:
extern int foo(void);
static int foo(void)
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
尝试使用GCC进行编译
$ gcc -Wall -std=c99 1.c
1.c:3:12: error: static declaration of ‘foo’ follows non-static declaration
1.c:1:12: note: previous declaration of ‘foo’ was here
1.c:3:12: warning: ‘foo’ defined but not used [-Wunused-function]
Run Code Online (Sandbox Code Playgroud)
那么,我该如何声明静态函数呢?
我已经读过全局变量和静态全局变量之间的区别在于全局变量可以通过extern在另一个实现文件中引用,而静态全局变量仅局限于该实现文件.看到这两个问题,以了解更多信息:[ 1,2 ].
据我了解,这是指下列foo()
和bar()
应相同链接.这两个功能只能用于MyClass
.
//MyClass.h
Class MyClass{
private:
static void foo();
};
//MyClass.cpp
void MyClass::foo(){}
static void bar(){}
Run Code Online (Sandbox Code Playgroud)
我可以看到foo()
声明更常见,因为它让头文件更完整地布局整个类(即使你不能/不应该使用私有的东西),但是不好的做法声明一个类似的函数bar()
(隐藏自头文件)?
对于上下文,我定义了一个WNDPROC
需要静态工作的Windows消息,但这是一个相当丑陋的声明,我不确定是否应该将它完全隐藏在实现文件中,或者继续在头文件中声明它.
我有这个测试程序,使用#define
常量:
#include <stdio.h>
#define FOO 1
int main()
{
printf("%d\n", FOO);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用"Apple LLVM版本10.0.0(clang-1000.11.45.5)"编译时,我得到8432字节的可执行文件.这是装配清单:
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 10, 14
.globl _main ## -- Begin function main
.p2align 4, 0x90
_main: ## @main
.cfi_startproc
## %bb.0:
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset %rbp, -16
movq %rsp, %rbp
.cfi_def_cfa_register %rbp
subq $16, %rsp
leaq L_.str(%rip), %rdi
movl $1, %esi
movl $0, -4(%rbp)
movb $0, %al
callq _printf
xorl %esi, %esi
movl %eax, -8(%rbp) ## 4-byte Spill
movl %esi, …
Run Code Online (Sandbox Code Playgroud) 我被告知,无法从其他文件访问static
在一个.c
文件中定义的函数.但是在下面的程序中,我可以static void show()
从另一个文件访问该函数.我对static
C 中函数的理解是错误的吗?
啊(第一档):
static void show()
{
printf("I am in static show function in a.c");
}
Run Code Online (Sandbox Code Playgroud)
bc(另一个文件):
#include"a.h"
void main()
{
show();
}
Run Code Online (Sandbox Code Playgroud) 我已经看到C/C++代码使用在函数签名中声明的extern"C",并且还在将CP头包含到CPP文件中时使用.
但有些函数只是在签名之前声明extern(没有"C").
QN1:
这两种定义函数的方式是否具有相同的效果,还是它们意味着不同的东西?
对不起,如果我很傻,但我无法通过谷歌找到这种差异.
例如:
extern int someFunction( void *ret_val);
extern "C" int someFunction( void *ret_val);
Run Code Online (Sandbox Code Playgroud)
QN2:
如果函数在其签名中声明了extern,那么相应的头文件是否必须包含在extern"C"块中?
正如评论中的另一个用户所指出的那样,标记的副本并不完全满足此处的问题.我正在编辑,以便将来其他人可能不会误导成另一个问题.
我相信声明为的 C++ 成员函数static
具有内部链接。当我将 libbar.cpp/libbar.hpp (如下)编译为共享对象时,我发现我可以从单独的(主)程序调用test1
两者。test2
为什么静态成员函数test2
在其翻译单元之外可用?
// bar/libbar.hpp
struct Foo
{
void test1();
static void test2();
};
// bar/libbar.cpp
#include <iostream>
void Bar::test1() { std::cout << __PRETTY_FUNCTION__; }
void Bar::test2() { std::cout << __PRETTY_FUNCTION__; }
Run Code Online (Sandbox Code Playgroud)
我使用 编译共享对象并$CXX libbar.cpp -shared -fpic -o libbar.so
使用main
编译程序(如下)$CXX -I bar -L bar main.cpp -Wl,-rpath,$PWD/bar -lbar
。我在 Debian 上使用 GCC 和 Clang。
// main.cpp
#include "libbar.hpp"
int main(int argc, char *argv[])
{
Bar b{};
b.test1(); …
Run Code Online (Sandbox Code Playgroud) 我有在g ++上重现的问题.VC++不会遇到任何问题.所以我有2个cpp文件:
1.cpp:
#include <string>
#include <iostream>
extern const std::string QWERTY;
int main()
{
std::cout << QWERTY.c_str() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
2.cpp:
#include <string>
const std::string QWERTY("qwerty");
Run Code Online (Sandbox Code Playgroud)
没有魔法,我只想将字符串常量放入分隔文件中.在链接时ld产生一个错误:"未定义引用`_QWERTY'"第一个想法将两个声明包装成"extern"C"" - 没有帮助.错误和非c ++ _QWERTY仍然存在.
在此先感谢您的任何建议
我在头文件中声明了一个静态无序映射,如下所示:
static boost::unordered_map<KeyAction, sf::Key::Code> WindowKeyMap;
Run Code Online (Sandbox Code Playgroud)
在同一个头文件中,我有一个用一些值填充地图的函数:
static void Initialize(std::string &file)
{
WindowKeyMap[MoveLeft] = sf::Key::Code::Left;
WindowKeyMap[MoveRight] = sf::Key::Code::Right;
WindowKeyMap[MoveUp] = sf::Key::Code::Up;
WindowKeyMap[MoveDown] = sf::Key::Code::Down;
std::cout << std::endl << WindowKeyMap.size() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
稍后在我的程序中,在一个单独的类/函数中,我尝试读取其中一个值:
std::cout << std::endl << WindowKeyMap.size() << std::endl;
auto test2 = WindowKeyMap[MoveRight];
Run Code Online (Sandbox Code Playgroud)
但地图总是空的.控制台的输出始终是初始化例程的4,然后是第二个cout的0.我认为静态地图在程序中是持久的,所以我对我的静态地图如何空洞感到有些困惑.任何人都能解释一下吗?
谢谢
我写的
// In file t.h
#ifndef __t_h__
#define __t_h__
static int abc;
#endif
Run Code Online (Sandbox Code Playgroud)
-
//In main.c
#include <stdio.h>
#include "t.h"
int main()
{
abc++;printf("%d \n", abc);
test();
}
Run Code Online (Sandbox Code Playgroud)
- -
//In test.c
#include <stdio.h>
#include "t.h"
void test()
{
abc++;
printf("%d \n", abc);
}
Run Code Online (Sandbox Code Playgroud)
当我运行该项目,我发现output
的abc is 1 and 1
.但是当我改变它int abc
时t.h
.的输出abc = 1 and 2
.为什么静态不会在控件到达test.c
文件时保留该值.如果它不会保留那么为什么它不应该提供错误作为static variable can not be shared between/among
文件?
我有一个项目,其情况是调用了错误对象的函数。
为了简化它,我在 Visual Studio 中创建了一个新的 CPP 项目。该项目有 3 个文件(附在底部),其中包含 2 个模块:导出的_1 和导出的_2,其中包含类 base_t 并覆盖接口类的虚函数。
当尝试调用一个对象的虚函数时,我发现正在调用的是另一个对象的函数。
我还打开了地图文件,发现链接的方法是错误的。
基础.hpp:
#ifndef BASE_HPP
#define BASE_HPP
extern int globalFlag;
class base_t {
public:
struct callBack_t {
virtual void virtualFunction(void) = 0;
};
base_t(callBack_t& callBack)
: _callBack(callBack) {}
void run() { _callBack.virtualFunction(); }
callBack_t& _callBack;
};
#endif //BASE_HPP
Run Code Online (Sandbox Code Playgroud)
派生_1.cpp:
#include "base.hpp"
class derivedCallBack_t : public base_t::callBack_t
{
public:
void virtualFunction(void) {
globalFlag = 1;
}
};
class derived_1_t
{
public:
derived_1_t(void);
derivedCallBack_t* _derivedCallBack;
base_t _base;
}; …
Run Code Online (Sandbox Code Playgroud)