【问题标题】:Avoiding too much casting避免过多的铸造
【发布时间】:2010-11-24 22:35:13
【问题描述】:

我目前正在从事一个涉及在图表中搜索和移动元素的项目。我认为 igraph 包非常适合我的简单需求,但是,由于我习惯于使用 java,有些事情并不清楚。

例如,为什么创建 igraph 包的人将整数等基本元素重新定义为 'igraph_integer_t' ? 有没有办法避免每次我调用他们库的函数时都必须将所有内容转换回整数,因为这会使代码变得非常混乱?

【问题讨论】:

标签: c casting integer igraph


【解决方案1】:

作为 igraph 的作者之一,我确实意识到这是/曾经是在项目开始时做出的一个有问题的设计决定。最初的意图实际上是“添加一层抽象”:在应用程序到处使用int 之前,我们已经使用科学源代码,并且由于溢出问题,我们不得不将每个int 替换为long all跨源代码以使程序能够解决我们遇到的问题。这就是为什么我们有igraph_integer_t 而不是简单的intlong - 如果您发现igraph_integer_t 数据类型对于您的问题来说太小,您只需更改源代码中的一处即可。

回想起来,上述情况非常罕见,因此它可能是一个非常薄弱的​​论点。更复杂的是,igraph_integer_t 被定义为double,因为担心long 数据类型在所有平台上都不够用。 (我现在能想到的一种情况是在大图中计算图案 - 图案的数量虽然是整数,但很容易超过旧平台上 long 数据类型的限制)。由于在做出关于igraph_integer_t 的决定时当时不在该项目周围,所以这可能不是确切的原因,这正是我认为可能的原因。如果您对血腥细节感兴趣,请随时在igraph-help mailing list 上提问。无论如何,我直接大量使用 igraph 的 C 核心(因为我负责 Python 包装器),所以我可以肯定地说,除了两种情况外,不需要在 igraph_integer_t 和其他数据类型之间进行强制转换:

  1. printf 中使用 igraph_integer_t 值时。您要么必须将igraph_integer_t 转换为long 并在格式字符串中使用%ld,或者不进行任何转换并在格式字符串中使用%g(这隐含依赖于igraph_integer_t 作为@ 987654342@)。

  2. 使用igraph_integer_t 索引数组时。您显然必须将其转换为 long

【讨论】:

  • 哇。哇。将类型命名为“整数”并将其定义为浮点类型。正如您所说,这会导致许多不明显的故障:不仅是阵列问题,还有 % 运算符的完全失败和 / 运算符的不当行为。至少感谢您承认这可能是个坏主意。
  • 顺便说一下,+1 以获得来自来源的非常丰富的答案。
  • 如果有人还在读这个:igraph_integer_t 现在在源代码中被定义为int,而不是double
【解决方案2】:

这是一个相当讨厌的做法,许多图书馆无缘无故地做。查找igraph_integer_t 的类型。如果它是int,我希望它是,只需在任何地方使用int 并假装igraph_integer_t 不存在。完全不需要演员表。所有整数(和浮点)类型都在 C 中隐式转换,并且 C typedef 类型无论如何都不会被认为与它们的定义不同。

【讨论】:

    【解决方案3】:

    我不知道这是否可能(我不知道这个包),但是您应该在自己的应用程序中使用 igraph_integer_t,或者围绕 igraph 构建一个框架供您与之通信。

    问题是,如果您使用了错误大小的整数(短整数与长整数、有符号与无符号等),那么您可能会遇到一些很难找到的非常古怪的错误。我将构建一个框架来与 igraph 交互,该框架为您正在使用的库和编译器选择适当大小的 int。我会避免强制转换,除非在这个框架中你知道它应该是安全的。

    简而言之:添加一个抽象层。

    【讨论】:

    • 这只是库作者的一种错误做法;没有正当的借口。如果他们需要特定大小的整数类型,他们的 API 应该使用该大小的标准类型,例如int32_t。如果他们想要一个随平台变化的“正常”整数大小,那就是intlong,他们应该使用其中一种类型。
    • @R.. 我当然同意,但是如果您现在需要使用该库,那并不能解决手头的问题...对吗?
    • 确实如此。只需查看igraph.h 或其他名称,找到igraph_integer_t 的定义(我99% 肯定会简单地是int),然后像往常一样使用int
    • @R.. 正如我所说,我不知道图书馆。但是,如果您以编译的形式收到它,那么更改它并不是最好的主意。我确实需要指出一点不同意见:我不知道图书馆作者制作新类型的意图。例如,他们可能想要有保证的固定大小类型。也许图书馆是一个巨大的东西,做出改变会太耗时。我的观点是,你拥有图书馆给你的东西:解决它或使用不同的图书馆。
    • 这不会改变库。绝对不需要更改任何库文件、源代码或头文件。只需在您自己的与库接口的代码中使用正确的类型(int 或类似类型)。仅仅因为foo.h 充满了foo_integer_t 的废话并不意味着您必须在自己的代码中编写foo_integer_t
    猜你喜欢
    • 1970-01-01
    • 2011-05-09
    • 2022-08-12
    • 2023-03-16
    • 1970-01-01
    • 2014-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多