首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同一个f2c生成的C代码,用gcc在两个平台上构建,结果不同

同一个f2c生成的C代码,用gcc在两个平台上构建,结果不同
EN

Stack Overflow用户
提问于 2021-09-17 10:00:12
回答 2查看 95关注 0票数 0

我们的代码有一个奇怪的问题,几年来我们在几个平台上使用了相同的代码,但是今年我们需要在64位的RHEL 8系统上构建我们的软件。

在构建过程中,我们需要使用F77工具将一些f2c代码转换为C代码。

在此转换处理过程中,内存中的一些变量被定义为输出C文件中的这样的变量。

代码语言:javascript
复制
#define v_hhdcb__ ((shortint *)&dovit_1 + 1608) /* works perfectly */
#define v_cncal__ ((integer *)(&dovit_1 + 5)) /* dovit_1 is a an array of short /*

在我们所有的系统(HP,AIX,Ubuntu,openSUSE)上,当我们使用GCC构建C代码时,我们都获得了良好的价值。

在Opensuse上:读取的v_cncal值位于dovit_1地址+5x短类型大小(2) == > (10)上

但是在RHEL上,相同的C代码返回一个错误的地址值:

在RHEL 8上:读取的v_cncal值位于dovit_1地址+5×int类型大小(4) ==> (20),但dovit_1short数组而不是int数组。

GCC版本在case 8.4和相同的f2c编译器中

有什么不对的?

更新

在调试期间,我们尝试手动修改C代码,如下所示:

代码语言:javascript
复制
#define v_cncal__ ((integer *)(&dovit_1 + 5*sizeof(shortint))) /* works */

但是这个C代码是由f2c生成的,我认为最好的方法是让f2c开发团队知道发生了什么。

更新1

如何声明dovit_1:

代码语言:javascript
复制
/* testdyF.f -- translated by f2c (version 20181026).
   You must link the resulting object file with libf2c:
        on Microsoft Windows system, link with libf2c.lib;
        on Linux or Unix systems, link with .../path/to/libf2c.a -lm
        or, if you install libf2c.a in a standard place, with -lf2c -lm
        -- in that order, at the end of the command line, as in
                cc *.o -lf2c -lm
        Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,

                http://www.netlib.org/f2c/libf2c.zip
*/

union {
    struct {
        shortint dovita[1];

    } _1;
    struct {
        doublereal eqv_pad[1];

    } _2;
} dovit_;

#define dovit_1 (dovit_._1)
#define dovit_2 (dovit_._2)

/* Table of constant values */

static integer c__9 = 9;
static integer c__1 = 1;
static integer c__2 = 2;
static integer c__3 = 3;

shortint        *__dovit;
#undef dovit_1
#define dovit_1 __dovit[0]

/* CCCC Tag pour ajout routine d attachement shm */
#include <SHM_INIT.c>

/* _SHM_INIT */
/* Main program */ int MAIN__(void)
{
    /* Builtin functions */
    integer s_wsle(cilist *), do_lio(integer *, integer *, char *, ftnlen),
            e_wsle(void);

    /* Local variables */
#define v_pc__ ((shortint *)&dovit_1 + 288100)
#define v_cp__ ((shortint *)&dovit_1 + 288169)
#define v_ct__ ((shortint *)&dovit_1 + 294500)

...
EN

回答 2

Stack Overflow用户

发布于 2021-09-17 10:06:40

这是未定义的行为,因为它违反了严格的混叠规则。当您取消对integer *的引用(我相信它是int *)

其结果是瑞银“工作”的最常见方式之一--在不同平台上运行时,使用不同的编译器获得不同的结果。

票数 0
EN

Stack Overflow用户

发布于 2021-09-17 10:16:53

正如answer中所述,您触发UB是因为违反了严格的别名规则。

但是,我想您的问题可能是由无效的对齐引起的。表达式(&dovit_1 + 5))看起来非常可疑,因为它没有正确地对齐指向4字节长int的指针.有些平台只允许正确对齐指针,编译器通过“调整”指针来利用这一点。

顺便说一句。v_cncal__读取的值位于dovit_1地址+5 x short int类型size (2)",而不仅仅是"int (大小4)“。据我理解,dovit_1的类型是short int

我想指针算法应该在转换之后执行。替换

代码语言:javascript
复制
#define v_cncal__ ((integer *)(&dovit_1 + 5)) 

使用

代码语言:javascript
复制
#define v_cncal__ ((integer *)&dovit_1 + 5)

有用吗?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69221455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档