【问题标题】:gcc windows declared inside parameter list will not be visible outside of this definition or declaration在参数列表中声明的 gcc 窗口在此定义或声明之外将不可见
【发布时间】:2022-06-14 06:47:14
【问题描述】:

我有一个头文件和 C 文件放在同一个目录中......头文件显然只是声明了一些东西,而 C 文件定义了它们。据我了解,这是正确的方法。链接器似乎看不到它。 (我目前正在试验线性探测,所以我知道代码在发生碰撞时可能无法工作,但它是有效代码,因此应该编译。)

这是标题:

#pragma once

#include <stdint.h>
#include <stdlib.h>
#include <string.h>



struct Header {

    /* key will always be present */

    char* key;

    /* value can be blank / null */
    
    char* value;
    
    /* RFC conforming; index of the header so we can use a hashmap */

    int index;

};

struct HashTable {

    struct Header** headerArr;

    uint16_t size;

    /* this will start at the size of the static table then be used to fill the index field of the Header struct before being placed within the array */

    int currentDynamicIndex;


};

/* init the hash table to a given size */

uint8_t initHashTable(struct HashTable* hashTable);

/* maps a struct to a value within the hashmap */

uint32_t hash(struct HashTable* hashTable, struct Header* header);

/* add a header pair to the hash table */

uint8_t add(struct HashTable* hashTable, struct Header* header);

/* find index given a value */

int lookup(struct HashTable* hashTable, struct Header* header);

/* delete an element from the hashmap */

uint8_t delete(struct HashTable* hashTable, struct Header* header);

C 文件包含头文件,然后开始定义函数:


#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#include "hash.h"


uint32_t hash(struct HashTable* hashTable, struct Header* header) {

    /* loop over both values in the header struct and add their ascii values to get a different number each time */

    uint32_t finalNumb = 0;

    size_t strLen = strlen(header->key);

    for (size_t x = 0; x < strLen; ++x) {

        finalNumb += (int)header->key;

        finalNumb = (finalNumb * (int)header->value) % hashTable->size;

    }

    /* if the header value struct is not empty, add it too */

    if (header->value != NULL) {

        strLen = strlen(header->value);

        for (size_t x = 0; x < strLen; ++x) {

            finalNumb += (int)header->value;

            finalNumb = (finalNumb * (int)header->value) % hashTable->size;

        }
    }

    return finalNumb;

}

uint8_t initHashTable(struct HashTable* hashTable) {

    /* this needs to be set to the size of the static table + 1 (since the 0th index is not a thing in the RFC) */

    hashTable->currentDynamicIndex = 62;

    hashTable->headerArr = calloc(hashTable->size, sizeof(struct Header));

    if (hashTable->headerArr == NULL) {

        /* calloc error */

        return 0;

    }

    return 1;

}

uint8_t add(struct HashTable* hashTable, struct Header* header) {

    uint32_t index = hash(hashTable, header);

    /* check if the index is occupied first */

    if (hashTable->headerArr[index] != NULL) {

        /* its occupied so use linear probing which is just +1 */

        uint32_t newIndex = index += 1;

        while (hashTable->headerArr[newIndex] != NULL) {

            newIndex += 1;

            if (hashTable->size <= newIndex) {

                newIndex = 0;

            }
        }

        return hashTable->headerArr[newIndex];

    }

    hashTable->headerArr[index] = header;

}

int lookup(struct HashTable* hashTable, struct Header* header) {

    /* the structs that are provided wont have an index field that isnt NULL but the ones in the array will */

    uint32_t index = hash(hashTable, header);

    if (hashTable->headerArr[index] != NULL && strcmp(header->key, hashTable->headerArr[index]->key) == 0 && strcmp(header->value, hashTable->headerArr[index]->value) == 0) {

        return hashTable->headerArr[index]->index;

    }

    return -1;

}

uint8_t delete(struct HashTable* hashTable, struct Header* header) {

    uint32_t index = hash(hashTable, header);

    /* check if the index is occupied first */

    if (hashTable->headerArr[index] != NULL) {

        hashTable->headerArr[index] = NULL;
        
        return 1;

    }

    return 0;

}

int main(int argc, char* argv[]) {

    printf("ok\n");

    return 1;
    
}

这可能是什么原因?之前所有与此相关的堆栈溢出答案似乎都是因为结构位于函数声明之后。

hash.c:96:19: warning: 'struct HashTable' declared inside parameter list will not be visible outside of this definition or declaration
 int lookup(struct HashTable* hashTable, struct Header* header) {
hash.c: At top level:
hash.c:96:48: warning: 'struct Header' declared inside parameter list will not be visible outside of this definition or declaration
 int lookup(struct HashTable* hashTable, struct Header* header) {

-H 的输出

... C:/Strawberry/c/lib/gcc/x86_64-w64-mingw32/8.3.0/include/stddef.h
.... C:/Strawberry/c/x86_64-w64-mingw32/include/stddef.h
. C:/Strawberry/c/x86_64-w64-mingw32/include/string.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/sec_api/string_s.h
... C:/Strawberry/c/x86_64-w64-mingw32/include/string.h
. C:/Strawberry/c/x86_64-w64-mingw32/include/stdio.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/_mingw_print_push.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/_mingw_off_t.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/swprintf.inl
.. C:/Strawberry/c/x86_64-w64-mingw32/include/sec_api/stdio_s.h
... C:/Strawberry/c/x86_64-w64-mingw32/include/stdio.h
.. C:/Strawberry/c/x86_64-w64-mingw32/include/_mingw_print_pop.h
. hash.h

重命名文件似乎确实有效。我现在只收到一些演员表错误。 @Jonathan Leffler 建议的解决方案。不确定在 c 标准库中哪个文件会被命名为 hash.h/.c,因为没有实现这样的数据结构

【问题讨论】:

  • 如何调用链接器?
  • gcc -c hash.c 和 hash.c 是 c 文件的名称 & hash.h 是 .h 文件的名称
  • gcc -c 是编译器调用。你怎么称呼链接器?
  • 不确定你的意思,gcc -c 是我所能得到的,在它给我这些警告/错误之前
  • 查看更新的问题

标签: c


【解决方案1】:

struct HashTable 的声明首次出现在函数声明的参数列表中时,会出现消息“警告:在参数列表中声明的'struct HashTable'在此定义或声明之外不可见”。这不是链接器错误;是编译器告诉您 struct HashTable 没有事先声明将结构声明放入文件范围,因此它只出现在函数中。 (而且,由于有关结构标记的规则,这意味着,即使结构的声明稍后出现在文件范围内,它也将是与函数参数内声明的类型不同的类型。)

由于您显示的“hash.h”文件具有struct Header 的声明,并且您显示的“hash.c”文件包含“hash.h”,这意味着编译器没有看到相同的“hash.h” ” 你展示的。您粘贴到此问题中的内容位于文本编辑器中,其内容尚未写入磁盘文件“hash.h”,或者有多个“hash.h”文件并且编译器正在使用不同的文件,或者存在您粘贴的源代码与实际正在编译的源代码之间存在其他一些不匹配。您需要调查磁盘上的文件并修复实际正在编译的内容。

【讨论】:

    【解决方案2】:

    C 编译器按顺序工作,这意味着逐行。您需要重构头文件以反映在 c 文件中。我附上了一个示例程序供您参考,以便您可以更深入地了解它的工作原理。 这是main.c

    student_t record;
    record.id=1;
    strcpy(record.name, "Dog");
    record.percentage = 86.5;
    
    func(record);
    
    return 0;
    

    这是头文件test.h

    void func(student_t record); /** this is not working.**/
    struct student 
    {
        int id;
        char name[20];
        float percentage;
    }
    typedef struct student student_t;
    // void func(student_t record); /** this is working **/
    

    希望对你有帮助;)

    【讨论】:

      猜你喜欢
      • 2021-06-29
      • 1970-01-01
      • 2021-01-14
      • 1970-01-01
      • 2011-12-07
      • 2022-09-23
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      相关资源
      最近更新 更多