Dynamic Functionname - Cannot resolve extern symbol

172 views Asked by At

I am trying to generate function names dynamically with preprocessor directives (add a optional prefix).

The generation works and when gcc outputs me the code after the preprocessor (gcc -E), gcc tells me that the function has the right name.

But when i use this function in code, gcc throws an error with unresolved external symbol? (Link2019 / Link1120)

I'm not 100% sure how the linker works but theoretically gcc should run the preprocessor, build all the librarys (more exactly first the prototype and after the main the definition?) so there should be no problem? Do i have to add a special compiler option? A link?

My main:

#define _CRT_SECURE_NO_WARNINGS
#define STRING_FUNCTION_PREFIX my   // Defining a prefix for my string functions
#include <stdlib.h>
#include <stdio.h>
#include <string.h>                 // Original string functions
#include "string.h"                 // My string functions

#define ARRAY_SIZE 50
#define HALLO "HALLO"
#define WELT "WELT"

int main()
{
    char src1[ARRAY_SIZE], src2[ARRAY_SIZE], dst1[ARRAY_SIZE], dst2[ARRAY_SIZE];
    strcpy(src1, HALLO);
    strcpy(dst1, WELT);
    strcpy(src2, HALLO);
    strcpy(dst2, WELT);

    strcat(src1, dst1);
    mystrcat(src2, dst2);

    return 0;
}

My string.h

#pragma once
#include <stdlib.h>

#if defined STRING_FUNCTION_PREFIX
#define FUNCTION_PASTER(ARG1,ARG2) ARG1 ## ARG2
#define FUNCTION_EVALUATER(ARG1,ARG2) FUNCTION_PASTER(ARG1, ARG2)
#define FUNCTION_NAME(FUNCTION) FUNCTION_EVALUATER(STRING_FUNCTION_PREFIX, FUNCTION)
#else
#define FUNCTION_NAME(FUNCTION) FUNCTION
#endif

/*
 * \brief: Adds the string from src to the destination string
 */
void FUNCTION_NAME(strcat)(char *dst, char *src);

My string.c

#include "string.h"

void FUNCTION_NAME(strcat)(char *dst, char *src)
{
    int counter = 0, offset = 0;
    while (dst[offset] != '\0')
    {
        offset++;
    }

    dst[offset + counter] = src[counter];
}

Output for string.h when compiling with -E

1>  #line 11 "d:\\string.h"
1>
1>
1>
1>
1>  void mystrcat(char *dst, char *src);

Thanks for your Help!

2

There are 2 answers

0
dbush On BEST ANSWER

The STRING_FUNCTION_PREFIX directive is defined in main.c, but not in string.c. So when string.c is compiled, the substitution does not occur. If you compile string.c with gcc -E, you'll see the effect of this.

You need to put #define STRING_FUNCTION_PREFIX my at the top of string.h instead of in main.c. That way, any .c file that needs it has it defined and it's consistent in all places.

0
jxh On

You appear to be attempting to create an emulation of templates in C. If that is the case, you should treat the contents of string.c as a header file that needs to be included by someone that knows what value STRING_FUNCTION_PREFIX should be. If the string.c contents are a header file, rename it to make that clear, for instance, string_template.h.

Then, you can have a file mystring.c implemented as:

#define STRING_FUNCTION_PREFIX my
#include "string_template.h"