سؤال

I have this Yacc code:

...
%union{
    int counter;
    char* partial_code;
}
....
single_selection_predicate: STRING EQ SINGLE_QUOTATION STRING SINGLE_QUOTATION 
        {   $<counter>$ = 1;
            printf("Counter: %d\n", $<counter>$);
            int size = sizeof(char)*(strlen($<partial_code>1) + strlen($<partial_code>4) + 7);
            $<partial_code>$ = (char*)malloc(size);
            printf("Counter: %d\n", $<counter>$);}
        ;
....

I would expect the first and the second printf in the syntax rule related code block to print the same output. But, I get something like this:

Counter: 1
Counter: 7402224

Maybe some overflow is occurring, but I cannot figure out why. Could you help me?

هل كانت مفيدة؟

المحلول

Unions are not structs.

In your union, counter and partial_code occupy the same memory location. Your write to partial_code overwrites the assignment to counter.

%union{
    int counter;
    char* partial_code;
}

نصائح أخرى

To expand on Charlie's answer, you can easily stick a struct into the union:

%union{
    struct {
        int counter;
        char* partial_code;
    } code_and_counter;
    char *partial_code;
}
%token<partial_code> STRING
%type<code_and_counter> single_selection_predicate
%%
single_selection_predicate: STRING EQ SINGLE_QUOTATION STRING SINGLE_QUOTATION 
    {   $$.counter = 1;
        printf("Counter: %d\n", $$.counter);
        int size = strlen($1) + strlen($4) + 7;
        $$.partial_code = malloc(size);
        printf("Counter: %d\n", $$.counter);}
    ;

In addition, you should rarely if ever use the $<tag>X syntax -- you should ALWAYS declare the type of the token/non-terminal as shown above and let yacc stick the tag into the action code for you.

In addition, NEVER use sizeof(char) (it's always 1), and never explicitly cast the result of malloc.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top