【问题标题】:How to determine obscure c types如何确定晦涩的 c 类型
【发布时间】:2017-05-03 15:24:04
【问题描述】:

好吧,这是一个愚蠢的问题,因为我已经用 C 编码了一段时间,但我从来没有真正弄清楚。

C 库喜欢实现自己的晦涩数据类型,这些数据类型通常似乎只是对现有类型的重新实现(提示此问题的库是 http://man7.org/linux/man-pages/man2/gettimeofday.2.html)。

我的问题是:您到底应该如何弄清楚这些一次性数据类型实际上是什么?它们似乎从未在手册页中的任何地方定义,因此没有深入研究头文件的源代码,我不知所措。例如,从上面提到的手册页中,什么是“suseconds_t”,在一般情况下,我如何弄清楚它的详细信息?

【问题讨论】:

  • 一般文档不能指定特定于实现的内容。您知道sys/time.h 包含结构:从那里开始您应该找到类型的定义。或者您的特定平台/sdk 的文档应该深入描述类型。
  • 您可以use search。从搜索结果中我选择了sys_types header which defines suseconds_t
  • 既然你知道它在sys/time.h,你可以这样做:echo '#include <sys/time.h>' >/tmp/chocofoo.c && c99 -E /tmp/chocofoo.c | egrep '[[:blank:]]+tv_usec' ; rm /tmp/chocofoo.c;它在某些平台上也可能有所不同,具体取决于您是在 32 位还是 64 位模式下编译(甚至是 x86_64 Linux 平台上的 X32)。无论如何,我的 POSIX 手册页声明“time_tsuseconds_t 类型将按照<sys/types.h> 中的描述进行定义。该标头的 POSIX 手册页链接在 user694733 之前的评论中。
  • 通常。 grepping 出现了定义。
  • O/T:如果你真的想发疯,看看Windows data types。它的结构很好,但正是这种僵化的结构加上针对特定用例的特定类型让我抓狂。很容易理解为什么 WinForms、WPF 或任何新事物在 Windows 上变得比 Windows API 本身更受欢迎。我很感激 POSIX 相比之下需要这么少的数据类型!

标签: c


【解决方案1】:

suseconds_t 是一个有符号整数类型,可以适应一秒内的微秒数。类型是suseconds_t,不是别的。这些“晦涩”类型的全部意义在于让您使用它们而不是想“哦,我将只使用 int,因为这是我一直使用的”,然后您的程序在其他机器上或一段时间内变得不可移植未来。

您在“C 库喜欢...”中略带屈尊的语气是非常错误的。这不是一些不起眼的图书馆做一些不起眼的小有趣的事情。这是POSIX

【讨论】:

  • 可以说,POSIX 有点晦涩难懂。特别是因为它劫持了早在 POSIX 存在之前就已成为行业标准的 _t 类型命名约定。基本上,POSIX 背后的想法是“让我们说 UNIX 是标准的,然后让每个人都知道这个标准”。这不是您制定成功行业标准的方式。
  • 并没有试图居高临下。我不是说图书馆晦涩难懂,我说的是 suseconds_t 类型。而且我知道原因是抽象的,但是例如,我正在研究了解 suseconds_t 的基础类型(有符号整数?无符号整数?长?短?)会很有用的东西,因为我想要一些类型的大小的想法。是的,这会因系统而异,但我可以做出一些猜测,在这种情况下,这就是我所需要的。我在指定的手册页中找不到任何地方;我在哪里可以查到这些信息?
  • 好吧,就在昨天,五月四日,只是想想传递到晦涩难懂的一面,认为类型是向外部用户隐藏内部结构的某种方式,并使其成为可能以可移植的方式考虑微秒 :)
【解决方案2】:

大多数情况下,您应该编写代码以使底层类型无关紧要。 这就是可移植的、面向未来的代码的想法。在不同的平台上或升级中的类型可能会发生变化,现有代码应该会选择它。

虽然有潜在的缺陷。对于像susecond 这样的标量类型,您可能需要输出它,并且库应该提供一个PRI 样式的宏用于输出和一个SCN 样式的宏用于读取。见<inttypes.h>。 否则,您最终必须找到具体的类型。 这些宏(或等效的)很少被定义(根据我的经验),你必须在某个时候处理实现类型......

在不使用泛型(在 C 中是新的)并且没有 C++ 重载的情况下,您在将值传递给其他函数时可能会遇到麻烦。 你调用一个函数接受int,然后库或平台发生变化,susecond 的底层类型是long,你已经引入了一个安静的截断错误!始终启用所有警告!

您的 IDE 可能会让您将鼠标悬停在您需要的边界上并查找底层类型。但在可能的情况下,只需将类型声明为 susecond 并让编译器担心它。

在这种情况下这样做的原因是因为(我猜)在 16 位平台上 int 可能不适用于高达 999,999(微秒...)的值,这需要 long 但在 32 -bit 平台,int 可能是 32-bt 没问题。

16 位?你确定爷爷?该库不是新的,很可能可以移植到 16 位是完全合理的嵌入式系统。

【讨论】:

  • 我理解抽象,我只是想知道在哪里可以实际查找底层数据类型。通常抽象是好的,但在这种情况下,我希望弄清楚底层类型是 long、short、int 等。虽然它们的确切大小也会因系统而异,但我正在研究一些足够具体的东西只需了解底层类型就会有所帮助。有没有地方可以查找像 susecond 这样的底层类型?因为我在手册页中找不到对类似内容的任何引用。
  • @gmaster 这取决于您的编码环境。如果你有一个现代 IDE,你应该在编辑模式下悬停或右键单击符号,它将提供查看定义或声明的选项。否则,它会在文件中搜索以发现 this 被定义为在大量条件编译头中最终被定义为具体类型的其他内容。打猎很好!
猜你喜欢
  • 2016-03-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 2018-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多