C 中的 macOS 重复符号

问题描述 投票:0回答:1

我有一个大问题,我有一个程序,它会扫描您的所有电脑,找到重复的文件(相同内容的 int 文件)并创建硬链接而不是该文件。我使用 SHA256 计算控制和以与其他文件进行比较。我的程序由6个文件组成:Cleaner.c Cleaner.h SHA256.c SHA256.h HashMap.c HashMap.h main.c。当我尝试编译它时遇到问题。我有错误:

1 warning generated.
gcc -Wall -Wextra -o program main.o Cleaner.o HashMap.o SHA256.o
duplicate symbol '_k' in:
    main.o
    Cleaner.o
duplicate symbol '_k' in:
    main.o
    HashMap.o
duplicate symbol '_k' in:
    main.o
    SHA256.o
ld: 3 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

我尝试使用Makefile。 这是Makefile:

CC = gcc
CFLAGS = -Wall -Wextra

all: program

program: main.o Cleaner.o HashMap.o SHA256.o
 $(CC) $(CFLAGS) -o program main.o Cleaner.o HashMap.o SHA256.o

main.o: main.c Cleaner.h HashMap.h SHA256.h
 $(CC) $(CFLAGS) -c main.c

Cleaner.o: Cleaner.c Cleaner.h
 $(CC) $(CFLAGS) -c Cleaner.c

HashMap.o: HashMap.c HashMap.h
 $(CC) $(CFLAGS) -c HashMap.c

SHA256.o: SHA256.c SHA256.h
 $(CC) $(CFLAGS) -c SHA256.c

clean:
 rm -f program *.o

我不知道这个符号“_k”在哪里,也许在SHA256.h里,有

typedef struct
{
 uchar data[64];
 uint datalen;
 uint bitlen[2];
 uint state[8];
} SHA256_CTX;

uint k[64] = {
 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2};
void SHA256Transform(SHA256_CTX *ctx, uchar data[]);
void SHA256Init(SHA256_CTX *ctx);
void SHA256Update(SHA256_CTX *ctx, uchar data[], uint len);
void SHA256Final(SHA256_CTX *ctx, uchar hash[]);
char *SHA256(char *data, long strlen);

我从这个网站获取了 SHA256 的实现 https://www.programmingalgorithms.com/algorithm/sha256/c/

我尝试使用 GCC 但出现另一个错误:

black_daddy@air-aleksandr Куровая работа ОСИСП % gcc -o *.c    
SHA256.c:120:21: warning: passing 'char *' to parameter of type 'unsigned char *' converts between pointers to integer types where one is of the unique plain 'char' type and the other is not [-Wpointer-sign]
        SHA256Update(&ctx, data, strlen);
                           ^~~~
SHA256.c:59:42: note: passing argument to parameter 'data' here
void SHA256Update(SHA256_CTX *ctx, uchar data[], uint len)
                                         ^
1 warning generated.
Undefined symbols for architecture arm64:
  "_readFilesInDirectory", referenced from:
      _main in main-d6f236.o
ld: symbol(s) not found for architecture arm64

我认为这是由于错误链接造成的,因为创建了 obj 文件。

c macos duplicates arm64
1个回答
0
投票

我认为这是由于错误链接造成的,因为创建了 obj 文件。

该问题是在链接时“检测到”的,但它是由不正确的代码“引起”的。 C 语言规范的每个版本都有此规定或与其基本等效的规定: 如果在外部链接中使用了声明的标识符 表达式(除了作为 sizeof

_Alignof

运算符,其结果是整数常量),位于 整个程序应该只有一个外部定义 标识符;否则,不得超过一个。


(C17 6.9/5)

...

uint k[64] = { [...] }

... 所提供的标头中提供了

k
 的声明以及外部链接 
这也是一个定义

,在每个直接或间接作为该标头的源文件中。因此,如果程序的多个翻译单元包含该标头,并且至少有一个访问

#include
,则该程序就会违反语言规范。由此产生的行为是未定义的。根据编译器发出的诊断信息,您有四个不同的翻译单元k标头,并且显然其中至少一个访问
#include
(可能通过声明的函数之一)。
从历史上看,一些 C 实现已经接受了存在此类问题的程序。您可以通过将 
k
添加到您的编译和(特别是)链接标志来诱导您这样做。
但是,更好的方法是通过将 

-fcommon

的定义移动到 C 源文件之一,并更改标头以仅提供不带任何初始化程序的

k
声明来修复代码

© www.soinside.com 2019 - 2024. All rights reserved.