为什么这些静态函数在它们的文件之外工作?

Why are these static functions working outside their file?

我在名为 Grafico.h 的文件中定义了接下来的两个静态函数。

static inline interface_t * obtener_intf_por_nombre(nodo_t *nodo, char *nombre_if) {
    for (int i = 0; i < MAX_INTF_POR_NODO; ++i)
    {
        if(!nodo->intf[i]) return NULL;
        if(strncmp(nodo->intf[i]->nombre_if, nombre_if, TAM_NOMBRE_IF) == 0) {
            return nodo->intf[i];
        }
    }
    return NULL;
}

static inline nodo_t * obtener_nodo_por_nombre(grafico_t *topologia, char *nombre_nodo) {
    return obtener_elemento(topologia->lista_nodos, nombre_nodo);
}

在我的主文件中,我调用了这些函数而没有记住它们是静态的,并且我没有从编译器那里得到任何与之相关的警告或错误。

#include <stdio.h>
#include "Net.h"
#include "Grafico.h"
#include "Topologias.h"
#include "CommandParser/libcli.h"
#include "clired.c"

extern grafico_t *const_primera_topo();
grafico_t *topo = NULL;


int main(void) {
    inic_cli_red();
    topo = const_primera_topo();

    sleep(2);
    nodo_t *nodo_trans = obtener_nodo_por_nombre(topo, "R0");
    interface_t *interface_trans = obtener_intf_por_nombre(nodo_trans, "ethR0/0");
    char *mensaje = "Este es un mensaje de prueba[=11=]";
    printf("Llegamos hasta aquí señores. Fue un honor.\n");
    enviar_paquete(mensaje, strlen(mensaje), interface_trans);
    
    start_shell();
    return 0;
}

如果它有用,这是我的 makefile。

TARGET = $(BIN_DIR)/sim_tcp_ip
LIBS = -lpthread -L ./CommandParser -lcli -lrt
OBJS = $(OBJ_DIR)/prueba.o \
       $(OBJ_DIR)/ListaEnlazadaGenerica.o \
       $(OBJ_DIR)/Grafico.o \
       $(OBJ_DIR)/Net.o \
       $(OBJ_DIR)/Topologias.o \
       $(OBJ_DIR)/Com.o \
       $(OBJ_DIR)/Utiles.o \
       $(OBJ_DIR)/Capa2.o
BIN_DIR = ./bin
OBJ_DIR = ./obj
INC_DIR = ./inc
SRC_DIR = ./src
CFLAGS = -g -lpthread -Wall -I$(INC_DIR)

$(TARGET): $(OBJS) CommandParser/libcli.a
    mkdir -p $(BIN_DIR)
    gcc $(CFLAGS) $(OBJS) -o $(TARGET) $(LIBS)
    
$(OBJ_DIR)/%.o : %.c
    mkdir -p $(OBJ_DIR)
    gcc -c -MD $(CFLAGS) $< -o $@
    
CommandParser/libcli.a:
    (cd CommandParser; make)

-include $(OBJ_DIR)/*.d
    
.PHONY: clean
clean:
    rm -rf $(OBJ_DIR) $(BIN_DIR)
    (cd CommandParser; make clean)
all:
    make

这些静态函数的定义有问题吗?

当您#include一个文件时,相当于复制粘贴该文件的内容来代替该行。因此 static 函数在同一个编译单元中,因此与您在 .c 文件本身中定义的任何其他 static 一样可用。

问题是您已经在头文件中声明了它们,Graphico.h!

static 关键字只是意味着如果你将源 C 文件 prog.c 编译成目标文件 prog.o,那么 prog.c 中的任何静态函数都将很难编码为 prog.o 中的内存地址。也就是说,普通函数在 prog.o 的符号 table 中定义了一个条目,当 prog.o 与另一个目标文件链接时使用该条目,而静态函数则没有。