使用 char** argv 时如何避免指针运算
Posted
技术标签:
【中文标题】使用 char** argv 时如何避免指针运算【英文标题】:How to avoid pointer arithmetic when using char** argv 【发布时间】:2018-01-24 21:09:52 【问题描述】:当尝试打印第一个命令行参数时:
std::cout << argv[0] << std::endl;
clang-tidy 给出警告:
警告:'不要使用指针运算' 来自 [cppcoreguidelines-pro-bounds-pointer-arithmetic]
是否有另一种方法可以在不使用指针运算的情况下使用argv
的值?是不是通过任何明智的方法访问char**
都必须使用指针算法?
我很欣赏有一些专门的函数来处理命令行参数,但它们似乎过于繁重,无法简单地打印一个参数。
我正在使用c++
编写代码,使用clang
编译器并使用cmake
构建。
【问题讨论】:
如果只需要argv[0]
,可以使用*argv
。但除此之外,没有。
@spectras 从来不是一个数组。函数参数不能是数组。
这只是实施核心指南失控了。更好的实现应该能够识别main
的特殊情况,并且在这种情况下不再为指针算术而烦恼。
@hvd 准则应该对main
例外。这是一个众所周知的界面,不会改变,那么为什么要用这个警告来打扰开发人员呢?
@SergeyA 正如我在回答中指出的那样,可以在不以本指南支持的方式更改界面的情况下读取命令行参数。但我确实认为,如果他们至少解决它会很好。无论是通过例外处理还是展示如何在不违反准则的情况下实施例外,对我来说都没有太大关系。
【参考方案1】:
来自clang-tidy - cppcoreguidelines-pro-bounds-pointer-arithmetic:
指针应该只引用单个对象,指针算法很脆弱,容易出错。
span<T>
是一种经过边界检查的安全类型,用于访问数据数组。
是的:
是否有另一种方法可以在不使用指针运算的情况下使用 argv 的值?是不是通过任何明智的方法访问 char** 都必须使用指针运算?
你完全正确。但是,该指南是关于隐藏该指针算术,让辅助类在执行算术之前进行边界检查。您可以从argv
和argc
构造一个span<char*>
。例如。在 C++20 中你会写:
auto args = std::span(argv, size_t(argc));
然后使用args
而不是argv
。
【讨论】:
@SergeyA 听起来您根本不同意该指南。这是完全公平的,在这种情况下,不要打开那个警告。 我同意他们中的大多数人的观点,但我发现这个特殊的规则被认为很糟糕。每次访问的分支都不是我在代码中想要的。 C++20 中没有对std::span
的边界检查。
"constexpr reference operator[](size_type idx) const;
返回对序列中第 idx
元素的引用。如果 idx
超出范围,则行为未定义"
std::span
接受大小为size_t
(无符号类型),而argc
是int
(有符号类型)。如果没有显式转换,则会出现关于隐式有符号->无符号转换的警告。以上是关于使用 char** argv 时如何避免指针运算的主要内容,如果未能解决你的问题,请参考以下文章