c - clang 和 gcc 之间的行为差​​异?

标签 c linux macos gcc compiler-errors

我正在编写一个 C 函数来模拟给定地址跟踪的缓存。当使用 gcc 在我的 mac 上编译时,该函数按预期工作(真的很铿锵)。我的 mac 上的 gcc --version 返回以下内容:

Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 8.1.0 (clang-802.0.42)

当我使用 gcc 在 Linux 上编译相同的程序时,返回值相差很大,并且我的程序中的 eC 和 hC(缓存逐出计数器和命中计数器)为数十万,而它们应该低于 10。在 Linux 机器上输入 gcc --version,它会返回:

gcc(Ubuntu 4.9.3-8ubuntu2~14.04)4.9.3

这是程序:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    #include <limits.h>
    #include <getopt.h>
    #include "cachelab.h"

    typedef struct{
        int v;
        int t;
        int LRU;
    } block;

    typedef struct{
        block *blocks;
    } set;

    typedef struct{
        set *sets;
    } cache;

    void simulate(int s, int E, int b, char* file, int* hC, int* mC, int* eC)
    {
        int numSets = (1 << s);
        char operation;
        int address;
        int size;
        int curTag;
        int curSet;
        int maxLRU = 0;
        int curLRU = 0;
        int check = 0;

    cache c;
    set *sets = malloc(sizeof(set) * numSets);
    c.sets = sets;

    int i = 0;
    while(i < numSets)
    {
        c.sets[i].blocks = malloc(sizeof(block) * E);
        for (int j = 0; j < E; j++)
        {
            c.sets[i].blocks[j].v = 0;
            c.sets[i].blocks[j].t = INT_MIN;
            c.sets[i].blocks[j].LRU = 0;
        }

        i++;
    }

    FILE *f = fopen(file, "r");
    while(fscanf(f," %c %x,%d", &operation, &address, &size) != EOF)
    {
        check = 0;
        curTag = ((unsigned int) address) >> (s+b);
        curSet = (address >> b) & ((1 << s) - 1);
        for (int i = 0; i < E; i++)
        {
            c.sets[curSet].blocks[i].LRU++;
            if(c.sets[curSet].blocks[i].LRU >= maxLRU)
            {
                maxLRU = c.sets[curSet].blocks[i].LRU;
                curLRU = i;
            }
            if(curTag == c.sets[curSet].blocks[i].t)
            {
                *hC = *hC + 1;
                if (operation == 'M')
                {
                    *hC = *hC + 1;
                }
                c.sets[curSet].blocks[i].LRU = 0;
                check = 1;
            }
        }
        if(check == 0)
        {
            for(int i = 0; i < E; i++)
            {
                if(c.sets[curSet].blocks[i].v == 0)
                {
                    *mC = *mC + 1;
                    if (operation == 'M')
                    {
                        *hC = *hC + 1;
                    }
                    c.sets[curSet].blocks[i].v = 1;
                    c.sets[curSet].blocks[i].LRU = 0;
                    c.sets[curSet].blocks[i].t = curTag;
                    check = 1;
                    break;
                }
            }
        }
        if(check == 0)
        {
            *eC = *eC + 1;
            *mC = *mC + 1;
            if (operation == 'M')
            {
                *hC = *hC + 1;
            }
            c.sets[curSet].blocks[curLRU].t = curTag;
            c.sets[curSet].blocks[curLRU].v = 1;
            c.sets[curSet].blocks[curLRU].LRU = 0;
        }
    }
    }

    int main(int argc, char** argv)
    {
    int hitCount, missCount, evictionCount;

    int s, E, b;
    char *file;
    char opt;
    while((opt = getopt(argc,argv,"v:h:s:E:b:t:")) != -1)
    {
        switch(opt){
            case 'v':
                break;
            case 'h':
                break;
            case 's':
                s = atoi(optarg);
                break;
            case 'E':
                E = atoi(optarg);
                break;
            case 'b':
                b = atoi(optarg);
                break;
            case 't':
                file = optarg;
                break;
            default:
                exit(1);
        }
    }
    simulate(s, E, b, file, &hitCount, &missCount, &evictionCount);

    printSummary(hitCount, missCount, evictionCount);
    return 0;
}

编辑:

我知道这是由于 clang 和 gcc 之间的差异造成的。有谁知道我如何解决此差异?

这是cachelab.c:

/*
 * cachelab.c - Cache Lab helper functions
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "cachelab.h"
#include <time.h>

trans_func_t func_list[MAX_TRANS_FUNCS];
int func_counter = 0;

/*
 * printSummary - Summarize the cache simulation statistics. Student cache simulators
 *                must call this function in order to be properly autograded.
 */
void printSummary(int hits, int misses, int evictions)
{
    printf("hits:%d misses:%d evictions:%d\n", hits, misses, evictions);
    FILE* output_fp = fopen(".csim_results", "w");
    assert(output_fp);
    fprintf(output_fp, "%d %d %d\n", hits, misses, evictions);
    fclose(output_fp);
}

/*
 * initMatrix - Initialize the given matrix
 */
void initMatrix(int M, int N, int A[N][M], int B[M][N])
{
    int i, j;
    srand(time(NULL));
    for (i = 0; i < N; i++){
        for (j = 0; j < M; j++){
            // A[i][j] = i+j;  /* The matrix created this way is symmetric */
            A[i][j]=rand();
            B[j][i]=rand();
        }
    }
}

void randMatrix(int M, int N, int A[N][M]) {
    int i, j;
    srand(time(NULL));
    for (i = 0; i < N; i++){
        for (j = 0; j < M; j++){
            // A[i][j] = i+j;  /* The matrix created this way is symmetric */
            A[i][j]=rand();
        }
    }
}

/*
 * correctTrans - baseline transpose function used to evaluate correctness
 */
void correctTrans(int M, int N, int A[N][M], int B[M][N])
{
    int i, j, tmp;
    for (i = 0; i < N; i++){
        for (j = 0; j < M; j++){
            tmp = A[i][j];
            B[j][i] = tmp;
        }
    }
}



/*
 * registerTransFunction - Add the given trans function into your list
 *     of functions to be tested
 */
void registerTransFunction(void (*trans)(int M, int N, int[N][M], int[M][N]),
                           char* desc)
{
    func_list[func_counter].func_ptr = trans;
    func_list[func_counter].description = desc;
    func_list[func_counter].correct = 0;
    func_list[func_counter].num_hits = 0;
    func_list[func_counter].num_misses = 0;
    func_list[func_counter].num_evictions =0;
    func_counter++;
}

最佳答案

您忘记初始化计数器和标志,因此它们以未定义的值开始。以下几行:

int hitCount, missCount, evictionCount;
int s, E, b;

应该是:

int hitCount = 0, missCount = 0, evictionCount = 0;
int s = 0, E = 0, b = 0;

只是碰巧 Mac 上的初始值较低,因此您在 Mac 上也无法获得正确的结果(至少不能保证,因为初始值未定义)。

关于c - clang 和 gcc 之间的行为差​​异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43900484/

相关文章:

python - 加载共享库 : libssl. so.0.9.8 时出现 django runserver 错误:无法打开共享对象文件:没有这样的文件或目录

linux - 如何在while循环中并行处理多行文件?

c++ - 预期的无限递归,不返回函数

c - 使用 struct { ... char arr[1]; } 构建?

c - 将 FILE 指针传递给函数并收到错误消息 'FILE is an unknown type name'

iphone - 语义问题 - Xcode 实现不完整

objective-c - cocoa /ObjC : get CFBundleIdentifier of current process

c - 为什么下面的 do-while 循环有效?

c++ - 线程在 pthread_rwlock_t 中挂起

macos - 无法使用 XQuartz mac 打开 GUI 应用程序