解决Vscode中使用netdb.h的getaddrinfo和addrinfo会报错的方法

news/2025/1/10 16:37:54/

原文地址:https://kashima19960.github.io/2024/12/03/解决Vscode中使用netdb.h的getaddrinfo和addrinfo会报错的方法/,一般有最新的修改都是在我的个人博客里面,所以在当前平台的更新会比较慢,请见谅😃

前言

博主最近在学习c语言的socket编程,在调用netdb.h中的相关函数和变量api时,遇到了一些问题,因此本文将给出解决的方法,并且进行分析

博主的配置

  • wsl:ubuntu20.04发行版
  • vscode:1.95.3

问题的描述

使用addrinfo(属于netdb.h头文件)结构体变量的时候,vscode会报错

在这里插入图片描述

调用getaddrinfo()函数的时候,vscode也索引不到这个函数的定义
在这里插入图片描述

其实这个函数就位于netdb.h中,可以看到,这一部分是灰色的

在这里插入图片描述

但是使用gcc编译的时候,是能够正确编译链接的,说明程序是没有语法和语义错误的

在这里插入图片描述

因此我推测是vscode的c语言扩展的intellisense智能提示的问题,就是下图的这个扩展(不得不说微软的东西,屁事就是多😅)

在这里插入图片描述

解决的方法

我查阅了很多资料,最终也是找到了解决的方法。我的风格就是先告诉你怎么做,解决你的燃眉之急,至于为什么要这么做,之后我再娓娓道来😋所以如果你对原因分析不感兴趣的话,后面的分析和总结你可以跳过不看❤️

方法1:在插件设置中更改c standard

进入c/c++插件的设置中,找到这一栏
在这里插入图片描述

然后将c99修改成gnu的c语言标准,我试过了,修改成GNU的任意一个都行
在这里插入图片描述

可以看到已经不会报错了
在这里插入图片描述

方法2:定义_GNU_SOURCE

在代码文件中添加_GNU_SOURCE的宏定义

#define _GNU_SOURCE

或者在.vscode中新建一个c_cpp_properties.json,然后在这个文件中定义这个宏,我个人推荐这个做法,因为修改配置文件能作用于整个工程,上面那种只能作用于单个文件。

{"configurations": [{"name": "Linux","includePath": ["${workspaceFolder}/**"],"compilerPath": "/usr/bin/gcc","cStandard": "${default}","intelliSenseMode": "${default}","defines": ["_GNU_SOURCE"]}],"version": 4
}

分析与总结

现在来分析一下为什么会报错,造成报错的原因是什么。然后总结一下

原因分析

先说结论:netdb.h属于GNU 特有扩展

标准的c语言本身并不直接包含对netdb.h的支持,所以你现在明白为啥上面打开netdb.h文件后发现有一部分是灰色(说明没有被包含)了吧。

那么GNU的c标准,和普通的c标准有啥区别呢?简单来说就是在普通的c标准上加了很多扩展功能,netdb.h就是GNU特有扩展功能的一部分,所以解决方案2就是这么来的,将c standard切换成GNU C就行了

特性C99GNU99
标准遵循 ISO C99 标准C99 加上 GNU 扩展
扩展不支持 GNU 特有扩展支持 GNU 特有扩展
兼容性严格遵循标准允许使用非标准的 GNU 特性
默认设置不定义 __STRICT_ANSI__定义__STRICT_ANSI__ 以禁用所有 GNU 扩展
  • C99: 这是 1999 年发布的 C 语言标准(ISO/IEC 9899:1999)。它引入了许多新特性,如布尔类型、复合字面量、可变参数宏等。使用 c99 编译器选项时,代码将遵循这一标准。
  • GNU99: 这是基于 C99 标准的 GNU 扩展版本。使用 gnu99 选项时,除了 C99 的特性外,还可以使用 GNU 编译器(GCC)提供的一些额外功能和扩展。这些扩展可能包括额外的语法和库函数,这些在标准 C 中并不被支持。

那么_GNU_SOURCE这个宏又是哪来的?干嘛的?

_GNU_SOURCE是一个宏定义,用于启用GNU C库(glibc)中的许多非标准扩展和功能。定义这个宏后,程序可以访问一些POSIX标准中未包含的传统功能以及GNU/Linux特有的扩展接口。

所以当你定义了这个宏的时候,那么下面标准的所有功能都会启用:ISO C89、ISO C99、POSIX.1、POSIX.2、BSD、SVID、X/Open、LFS 以及 GNU 扩展。在 POSIX.1 与 BSD 发生冲突的情况下,POSIX 定义优先。

这就是解决方案1的由来,定义了这个宏之后就能启用GNU的扩展

总结

有一种说法是写程序都是三分在写,七分在调,我觉得说的很对,写程序最重要的反而不是编写代码,而是如何去调试代码,解决报错,总结问题,我在解决本文的问题的时候,上网查阅了很多资料,以前我并不会去在意C语言不同标准带来的差异,因为写的程序能跑就行😋。但是当你解决问题的时候会发现,你可能会接触到别人写的资料中不胜其烦的枯燥术语,难以理解的代码逻辑,当你经历这个过程后,你的code能力就提升了。

参考资料

  • C99 和 GNU99 的区别 - Undefined443 - 博客园
  • c - What does “#define _GNU_SOURCE” imply? - Stack Overflow
  • 关于__GNU_SOURCE 这个宏 - 颠覆者 - 博客园
  • Incomplete type error on struct addrinfo · Issue #2025 · microsoft/vscode-cpptools

http://www.ppmy.cn/news/1562018.html

相关文章

JAVA 使用apache poi实现EXCEL文件的输出;apache poi实现标题行的第一个字符为红色;EXCEL设置某几个字符为别的颜色

设置输出文件的列宽,防止文件过于丑陋 Sheet sheet workbook.createSheet(FileConstants.ERROR_FILE_SHEET_NAME); sheet.setColumnWidth(0, 40 * 256); sheet.setColumnWidth(1, 20 * 256); sheet.setColumnWidth(2, 20 * 256); sheet.setColumnWidth(3, 20 * 25…

【合作原创】使用Termux搭建可以使用的生产力环境(九)

前言 在上一篇【合作原创】使用Termux搭建可以使用的生产力环境(八)-CSDN博客中我们讲到了如何安装IDEA社区版,并在Termux中安装VNC服务器,在proot-distro的Debian中启动xfce桌面,并通过这个方式解决了IDEA社区版中无…

『SQLite』子查询可以这样用

摘要:本节主要讲子查询的使用,可以在查询、更新、修改、删除等操作中使用。 什么是子查询? 子查询是一种在 SELECT-SQL 语言中嵌套查询下层的程序模块。当一个查询是另一个查询的条件时,称之为子查询(Sub Query&#…

中文博客排版指南

标题 正确:(Markdown 语法) # 文章的标题## 文章内容的一级标题### 文章内容的二级标题#### 文章内容的三级标题原则: (1)文章内容的标题一般用 ## 和 ###。为保证层级的简单,请尽量避免出现…

el-table 使用el-form 表单验证

1. form定义时,需要定义tableData const supplyForm ref({ tableData: [] })const supplyFormRules reactive({bomNumber: [{ required: true, message: 请填写物料编号, trigger: blur }],bomName: [{ required: true, message: 请填写名称, trigger: blur }] }…

Solidity合约编写(三)

解决问题: 在 Solidity 合约中使用 Chainlink 获取 ETH/USD 的价格(汇率),需要使用 Chainlink 的 AggregatorV3Interface 接口。以下是一个样板代码,展示了如何在测试链(如 Goerli 或 Sepolia)…

相机镜头竞品选型的主要参考参数和选型方法

目录 一、镜头主要参数: 1. 焦距(Focal Length) 2.光圈(Iris) 3.对应最大CCD尺寸(Sensor Size) 4.接口(Mount) 5.景深(Depth of Field, DOF&#xff09…

VUE3组合式——响应式数据ref、reactive

VUE3 组合式 —— 响应式数据 ref、reactive 学习笔记 一、引言 在 Vue3 中,响应式数据是构建动态交互应用的关键部分。其中,ref 和 reactive 是处理响应式数据的重要函数,深入理解它们对于高效开发 Vue3 应用至关重要。 二、ref 函数 基…