- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我一直在空闲时间尝试伪造 C,并且遇到了一些我觉得很有趣的行为。我希望有人能帮助回答我提出的一些问题。为了简单起见,让我们将讨论限制在使用 gcc 进行编译。首先是代码(.h文件都有include guards):
啊.h
void print_a();
b.h
void print_b();
c.h
void print_c();
交流
#include "a.h"
#include "c.h"
#include <stdio.h>
void print_c(){
printf("Printing c from a");
}
void print_a(){
print_c();
}
BC
#include "b.h"
#include "c.h"
#include <stdio.h>
void print_c(){
printf("Printing c from b");
}
void print_b(){
print_c();
}
main.c
#include "a.h"
#include "b.h"
int main(int argc, char **argv){
print_a();
print_b();
return 0;
}
所以首先,我明白 a.c 和 b.c 都有 c.h 的实现。因此,我预计这样的编译会失败,因为编译器不知道 print_c 的哪个实现绑定(bind)到接口(interface):
gcc main.c a.c b.c
但是您会注意到 main.c 与 c.h 没有依赖关系。因此,当分别编译每个组件时,我有点惊讶地看到在链接器阶段失败了:
gcc -c a.c
gcc -c b.c
gcc -c main.c
gcc main.o a.o b.o
b.o: In function `print_c':
b.c:(.text+0x0): multiple definition of `print_c'
a.o:a.c:(.text+0x0): first defined here
collect2: error: ld returned 1 exit status
很明显,由于链接器还没有链接 print_c 的定义,所以我们仍然应该预料到这些错误。也就是说,我可以想到几个可能会出现问题的实际用例。例如,如果我在我的程序中使用了 log.h 接口(interface)的一些自定义实现,但我想包含一个在内部实现相同 log.h 接口(interface)的库怎么办?这引出了我的问题:
最佳答案
头文件包含函数原型(prototype)。函数原型(prototype)告诉编译器
按照惯例,头文件仅包含在一个源文件中定义但在其他源文件中使用的函数的函数原型(prototype)。
所以c.h不应该存在,a.h和b.h中的函数原型(prototype)需要参数列表。头文件应该是:
啊.h
void print_a( void );
b.h
void print_b( void );
源文件a.c 和b.c 可以改进如下。首先,始终在您自己的 header 之前包含标准 header (请参阅下面的注释)。其次,不需要包含 c.h,因为 print_c
在使用之前已定义。所以函数定义作为函数原型(prototype)。第三,print_c
需要一个参数列表:void print_c( void )
。 第四,也是重点,print_c
函数要声明为static
。static
关键字表示该函数仅在定义它的文件中可见,即它不是全局可见的。使用 static
关键字允许您在每个 .c 文件中重新定义函数。
所以你的源文件应该是这样的
交流
#include <stdio.h>
#include "a.h"
static void print_c( void ){
printf("Printing c from a\n");
}
void print_a( void ){
print_c();
}
BC
#include <stdio.h>
#include "b.h"
static void print_c( void ){
printf("Printing c from b\n");
}
void print_b( void ){
print_c();
}
main.c
#include "a.h"
#include "b.h"
int main( void ){
print_a();
print_b();
return 0;
}
注意:首先包含标准头文件的原因是标准头文件应该没有错误,而您的头文件可能没有。如果您的 header 中存在语法错误,并且您的 header 包含在标准 header 之前,则该错误最终可能会被报告为标准 header 中的错误,这会变得非常困惑。
关于c - 具有 "Independent"目标文件的多个定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34170867/
我对贝叶斯网络有一些误解。我的主要误解是独立和有条件的独立!! 如果例如我必须计算P(Burglary|Johncall) , 是吗P(Burglary|Johncalls)=P(Burglary)因
在以下代码中,set 方法更改 Calendar 类的字段值。字段YEAR 被声明为static int YEAR。那么为什么通过创建 Calendar 类的两个对象,一个对象的更改会反射(refle
假设我已经掌握了这两个事实:- CreateProcess() 启动一个进程并让您的程序在它运行时继续运行,但是当您的程序完成时,子进程会随之关闭。此外,您的程序必须注意子进程何时退出,以便它可以正确
是否可以定义一个正则表达式模式来检查例如。对于 3 个独立于它们在主字符串中位置的术语? 例如。我的字符串类似于 "click here to unsubscribe: http://www.url.
我有一系列计算一些统计数据的“命令”(实际上是调用 bash shell 函数)。一般来说,每个命令都与所有其他命令无关,有时有些命令可能会花费比预期更多的时间。 到目前为止,我有一个调用这些命令的
我一直在空闲时间尝试伪造 C,并且遇到了一些我觉得很有趣的行为。我希望有人能帮助回答我提出的一些问题。为了简单起见,让我们将讨论限制在使用 gcc 进行编译。首先是代码(.h文件都有include g
我遇到了以下代码,并被告知这意味着 COL_8888_RED 是“字节序独立的”。为什么?是什么让这个端独立?(我问过最初的编码员,但他们没有回复我……哎呀,也许他们也不知道。) union _col
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 3年前关闭。 Improve t
我决定模拟一个教科书上的概率题: Three fair dice are rolled independently, what is the probability that one dice sho
我想尝试有关分布式文件同步/复制的想法。为了在用户工作时提高效率,我想实现某种守护程序来监视某些目录中的更改(例如/home/user/dirToBeMonitored 或 c:\docs 和 set
当我在Mac机器上的R(仅是默认的Mac R)中看到帮助页面时, > ?read.csv 它以漂亮的格式显示在新窗口中。 现在,我在Mac机器上使用Sublime文本3表示R(带有SublimeREP
我觉得这是 ui-router 的一个直接用例,但也许我错过了一些东西...... 我想要两个相邻的独立 View ,由它们自己的菜单控制。当我单击一个菜单上的 ui-sref 链接(或 $state
也许我在这里问了一个非常明显且愚蠢的问题,但我在 Google 上找不到任何信息,所以我开始: 为什么人们如此热衷于 Java 是平台无关的,而其他一些语言却不是。我的意思是,就我的理解而言,总的差异
FORTRAN 编程用户注释,第 1-2 章 ( Comparison of FORTRAN and C ),说: Fortran 90 supports useful features of C (
前段时间我对 BEM 方法产生了兴趣,并尝试在我的元素中使用它。我可能使用了它的一些修改版本,所以我的 css 看起来像这样: .block block .block__element 用于元素 .b
我想在数据库中创建一个没有特定大小的文本字段(在某些情况下它将存储长度未知的文本)——特定文本是序列化的简单对象(~ JSON) 最独立于数据库的方法是什么:- 没有指定大小的 varchar(不
WPF 文档和教程指出 WPF 与分辨率无关,据我所知,它会在不同分辨率(1600x1200 -> native 和 1024x768)和/或 DPI 设置下显示相同大小的窗口。但是,当我尝试示例应用
我是 Cygwin 的初学者。如果我有: cat output.txt | rm output.txt 我想在删除文件之前打印出结果,但是即使这些命令在单独输入到 Cygwin 时工作 find 也不
考虑以下 gilab-ci.yml 脚本: stages: - build_for_ui_automation - independent_job variables: LC_ALL: "
我在 Nhibernate 3.1 中有一个 JoinQueryOver 的 QueryOver Person类有一个Identity类的关联(一对一)Code 是 Person 类的字段,First
我是一名优秀的程序员,十分优秀!