Using the macro __LINE__ - C

4

Greetings!

I'm doing a C function that allows to obtain a more detailed record of what happens in the program, something similar to a debug , but trying to summarize things for the programmer.

I found the Preprocessor documentation CPP (GNU / Linux) and there indicated the different macros and constants that can be used in our program so that it is also can use functions and use these macros .

Thanks to this, carry out the following program:

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

/* Dump para variables */
#define dump(variable) {   \
    printf("La variable '%s' ocupa %d bytes\n", #variable, sizeof(variable)); \
}

/* Dump para funciones */
#define dumpf(){ \
    printf("Se llama a funcion %s()\n", __FUNCTION__); \
}

void funcion(int argumento){
    dumpf();
    printf("%d\n", argumento + argumento);
}

void sumar(int a, int b){
    dumpf();
    printf("%d + %d = %d\n", a, b, (a+b));
}

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

    /* Variables */
    int variableINT   = 45;
    char variableCHAR = 'A';
    char *variablePTR = "Hola Mundo";

    /* Debug de Variables*/
    dump(variableINT);
    dump(variableCHAR);
    dump(variablePTR);

    /* Debug de Funcion*/
    funcion(10);
    sumar(5, 5);

   return EXIT_SUCCESS;
}

This program allows us to know the weight in bytes of a variable thanks to the dump () function, it also lets us know what function we are calling by means of the < em> dumpf () .

Up to this point, the result of the console program is:

  

The variable 'variableINT' occupies 4 bytes

     

The variable 'variableCHAR' occupies 1 bytes

     

The variable 'variablePTR' occupies 4 bytes

     

Function is called function ()

     

20

     

It is called to add function ()

     

5 + 5 = 10

After that, to make a little more readable and easier to understand our "debug" , I wanted to add something that would indicate the line where the call to the function was being made, so So I made the following modification in the dumpf () :

/* Dump para funciones */
#define dumpf(){ \
    printf("Se llama a funcion %s() en la linea %d\n", __FUNCTION__, __LINE__); \
}

I added the macro LINE , which in theory tells us the line where the instruction is running.

But the result of the program is:

  

Function () is called on line 15

     

20

     

It is called to add function () in line 20

That is, it indicates the line where the function was originally called within each of the functions funcion () and sumar () , it does not indicate the line where It was really called the function, which is actually lines 37 and 38.

How would it be possible to obtain the line where the function call was made? Is there any problem with the LINE macro when included in a function? Since the Preprocessor is supposed to replace these values before compiling.

I thank you in advance for your help.

    
asked by Ivan Botero 25.01.2017 в 15:22
source

2 answers

5

What you are looking for is a macro that tells you that the function has been called from the X line and that will not work if you call the macro from the function itself ... Think that the message is being generated in compile time ... the compiler at that time does not know where you're going to call the function from.

To get what you want you should call the macro before to call the function (or adapt the macro so that it is able to call the function) ... in any case not it's too practical:

// "hack" para convertir el nombre de un parametro en una cadena
#define ___TOSTRING(x) #x
#define TOSTRING(x) ___TOSTRING(x)

#define dumpf(FUNC) \
    printf("Se llama a funcion %s() en la linea %d\n", TOSTRING(FUNC), __LINE__); \
    FUNC

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

    /* Variables */
    int variableINT   = 45;
    char variableCHAR = 'A';
    char *variablePTR = "Hola Mundo";

    /* Debug de Variables*/
    dump(variableINT);
    dump(variableCHAR);
    dump(variablePTR);

    /* Debug de Funcion*/
    dumpf(funcion)(10);
    dumpf(sumar)(5, 5);

   return EXIT_SUCCESS;
}

And the result would be:

La variable 'variableINT' ocupa 4 bytes
La variable 'variableCHAR' ocupa 1 bytes
La variable 'variablePTR' ocupa 4 bytes
Se llama a funcion funcion() en la linea 37
20
Se llama a funcion sumar() en la linea 38
5 + 5 = 10

If you're interested in having the execution traces maybe you should consider learning how to use the code debugger ... in programs as small as the one you sample, it does not make much sense to enter a trace system.

    
answered by 25.01.2017 / 15:45
source
1
  

How would it be possible to get the line where the call to the function was made?

No way. The information you are looking for is the stack trace which is determined at runtime while the macros as __LINE__ and __FUNCTION__ are tokens that the pre-processor translates into literals just before compiling.

That is, the macro __LINE__ written on line 100 will be translated by the literal 100 before compiling. The only way would be to pass to each function a parameter indicating the call point:

void funcion(int argumento, int linea){
    printf("%d\nllamada en %d\n", argumento + argumento, linea);
}

void sumar(int a, int b, int linea){
    printf("%d + %d = %d\nllamada en %d\n", a, b, (a+b), linea);
}

/*09*/int main(void)
/*10*/{
/*11*/    funcion(1, __LINE__);
/*12*/    sumar(3, 2, __LINE__);
/*13*/    return 0;
/*14*/}

The call to funcion(1, __LINE__) will be translated by the pre-processor to funcion(1, 11) while sumar(3, 2, __LINE__) will be translated to sumar(3, 2, 12) .

Maybe you're thinking that it's enough for you and you can use default parameters ... but it would not work:

/*01*/void funcion(int argumento, int linea = __LINE__){
/*02*/    printf("%d\nllamada en %d\n", argumento + argumento, linea);
/*03*/}
/*04*/
/*05*/void sumar(int a, int b, int linea = __LINE__){
/*06*/    printf("%d + %d = %d\nllamada en %d\n", a, b, (a+b), linea);
/*07*/}

int main(void)
{
    funcion(1);
    sumar(3, 2);
    return 0;
}

The previous code, when going through the pre-processor, would look like:

/*01*/void funcion(int argumento, int linea = 1){
/*02*/    printf("%d\nllamada en %d\n", argumento + argumento, linea);
/*03*/}
/*04*/
/*05*/void sumar(int a, int b, int linea = 5){
/*06*/    printf("%d + %d = %d\nllamada en %d\n", a, b, (a+b), linea);
/*07*/}

So the output of the program would be:

1
llamada en 1
3 + 2 = 5
llamada en 5

Which you already know is false, since the functions were called on lines 11 and 12.

Conclusion.

Check your compiler's documentation to see if you can access the stack trace during program execution.

    
answered by 25.01.2017 в 15:44