在 g++ 中编译具有未初始化全局的 C 程序时出现“值的多重定义”,但在 gcc 中则不然

2023-12-13

我试图了解头文件中 extern 和全局变量声明的用法,因此我想出了以下用 C 编写的测试程序。

main.c 文件

//main.c
#include "global.h"
#include <stdio.h>

int nExternValue = 6;

int main(int argc, char* argv[])
{
    printf("%d \n", nValue);
    printf("%d \n", nExternValue);

    AddToValue();

    printf("%d \n", nValue);
    printf("%d \n", nExternValue);
}

全局.h 文件

#ifndef _GLOBAL_H
#define _GLOBAL_H

//WRONG! do not declare a variable here
int nValue;

//OK! extern variable makes it a global accessable variable
extern int nExternValue;

//OK! function prototype can be placed in h file
int AddToValue();

#endif

和一个实现 AddToValue 函数的 AddValue.c 文件。

#include "global.h"

int AddToValue() {
    nValue++;
    nExternValue++;
}

我使用 gcc 编译了该应用程序,并运行它:

$ gcc main.c AddValue.c -o test
$./test
0 
6 
1 
7 

我使用 g++ 编译了该应用程序并收到以下链接器错误:

$ g++ main.c AddValue.c -o test
/tmp/ccFyGDYM.o:(.bss+0x0): multiple definition of `nValue'
/tmp/cc3ixXdu.o:(.bss+0x0): first defined here
collect2: ld returned 1 exit status

为什么 gcc 链接器不产生错误?我认为 nValue 变量会被声明多次,这会产生错误!

$ gcc --version
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ g++ --version
g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

C 和 C++ 是不同的语言。举个例子,上面的程序是一个有效的 C 程序,但是是格式错误的 C++ 程序。你违反了 C++ 的单一定义规则。 C中没有相应的规则。

当使用 gcc 编译时,您将上面的文本编译为 C 程序。当使用 g++ 编译时,您正在将上述文本编译为 C++ 程序。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 g++ 中编译具有未初始化全局的 C 程序时出现“值的多重定义”,但在 gcc 中则不然 的相关文章

随机推荐

  • 如何在 JavaScript 中添加元标记

    我想添加对于特定页面 但我的页面是在一个页面中呈现的HTML标签 单击不同模板时 只有内容会发生变化 所以我无法添加 in 部分 有什么办法可以添加 using javascript 您可以添加它 var meta document cre
  • 如何使用Flask获取客户端端口?

    我正在尝试使用 Flask 构建一个简单的 torrent 跟踪器 但遇到了一个问题 如果客户在NAPT请求中包含的网络 端口不正确 我想用 Flask 获取客户端连接端口 在 PHP 中像这样的函数 SERVER REMOTE PORT
  • RequestContext - RouteData 不包含操作

    因此 我创建了自己的 ControllerFactory 并且重载了 GetControllerSessionBehavior 以扩展 MVC 行为 为了完成我的自定义工作 我必须对被调用的操作使用反射 然而我偶然发现了一个奇怪的问题 我无
  • 并行继承层次结构真的是一种代码味道吗?

    我不知道如何在实践中避免并行层次结构 例如考虑一个必须在不同级别上创建 保存 编辑笔记的应用程序 它是一个基于 java swing 的应用程序 域层次结构 AbstractNote lt MonthNote lt DayNote lt P
  • 在 Rails 中设置可选字段

    我使用回形针将头像附加到用户身上 效果很好 但当新用户尝试注册时 它会抱怨头像太小且类型不正确 这就是我验证我的头像的方式 validates attachment size avatar less than gt 1 megabytes
  • Java中如何写入文本文件

    我正在用java做一个项目 我需要添加和修改我的 运行时的文本文件 该文件分组在 jar 中 我正在使用 class getResourceAsStream filename 这个方法我们 可以从类路径读取该文件 我想写入同一个文本文件 对
  • 使用 Google Apps 脚本将 Google Sheet 中的图表正确插入到文档中

    我想使用 Google Apps 脚本将图表从电子表格复制到文档中 插入图表是可行的 但存在 a 权限和 b 格式问题 可以按如下方式插入图表 var b d getBody var charts SpreadsheetApp getAct
  • 映射数组以设置空元素

    Given let input 0 1 2 7 我想得到 let output 1 22 333 4444 55555 666666 7777777 i e value equal key倍key 我怎么能够map 或等效 输入包括empt
  • JTree 延迟加载展开

    希望你一切都好 我有一个 JTree 我使用数据库查询 每个节点 延迟加载 我在屏幕上有一个按钮 当用户单击该按钮时 我会执行一些操作insert update delete在数据库中 然后将模型添加回Jtree仅使用 SQL 的根及其直接
  • 从 Html Agility Pack 下载中,我使用 9 个“HtmlAgilityPack.dll”中的哪一个?

    下载的 HTML Agility Pack zip 文件中有九个文件夹 Net20 Net40 Net40 客户端 Net45 sl3 wp sl4 SL4 windowsphone71 sl5 winrt45 我不知道这些文件夹名称的含义
  • 在 PHP 中将数组元素分配给变量

    我知道这是一个愚蠢的问题 但我被困住了 我有以下数组 Array type gt 8 message gt Use of undefined constant hola assumed hola file gt C wamp www WeC
  • 在 javascript(Angularjs) 中将对象数组转换为单个对象

    如何像这样转换对象数组 display name view dashboard value 1 display name view user value 0 to this view dashboard 1 view user 0 你可以尝
  • 在运行时重新加载 tomcat 日志记录?

    我们当前使用 Tomcat 7 并使用 Djava util logging config file 指定单个日志配置 并使用 Djava util logging manager org apache juli ClassLoaderLo
  • Android:分享到 Facebook Messenger 错误

    我已经尝试修复这个错误一周了 但仍然找不到问题所在 登录正常 但由于某种原因 共享到 Messenger 崩溃 我无法真正理解问题是什么 基本上 我将文本转语音保存到我的设备上 然后尝试共享它 文件保存到设备 我检查过 但Messenger
  • Flutter:创建覆盖进度条

    如何在 Flutter 中创建覆盖页面 基本上 今天我的页面中央有一个旋转器 现在 我希望当前页面淡出 90 不透明度 并在按下按钮时显示动画点 不知道该怎么做 感谢您的帮助 尝试用这个 class SamplePage extends S
  • 将曲线/模型拟合到 1/x 数据

    我有一个遵循 1 x 曲线模式的数据集 我想用模型来拟合数据的曲线 我尝试过使用多项式函数 但它看起来不太正确 因为多项式曲线备份 而我的数据渐近线在底部 我知道我在这里遗漏了一些术语 但是我该如何绘制曲线呢 1 x 曲线有名称吗 x lt
  • consteval 函数是否允许模板参数依赖于函数参数?

    在 C 17 中 以下代码是非法的 constexpr int foo int i return std integral constant
  • 剔除虚拟元素不适用于 Internet Explorer

    如果您在 Chrome 中运行此 Fiddle 则选择框会正确填充选项 A B 和 C 但是 如果您使用 Internet Explorer 版本 8 或 9 运行它 则它不起作用 我怎样才能修复这个小提琴以使其与 Internet Exp
  • VS 2013 中无需包含指令“math.h”即可使用 C++ 数学函数

    我很好奇为什么我可以在 C 中使用数学函数而不包含 math h 我无法通过谷歌搜索找到答案 这是我正在执行的简单代码 一切都在编译和运行 include
  • 在 g++ 中编译具有未初始化全局的 C 程序时出现“值的多重定义”,但在 gcc 中则不然

    我试图了解头文件中 extern 和全局变量声明的用法 因此我想出了以下用 C 编写的测试程序 main c 文件 main c include global h include