Skip to content

Invalid Go code when translating function pointer conditions #936

Description

@chisa22

c2go incorrectly translates a C function pointer used in an if condition into a non-boolean Go expression.
In C, a function pointer can be used directly as a condition. The expression if (f) is equivalent to checking whether the function pointer is not NULL. However, Go requires the condition of an if statement to be a boolean expression. A function value cannot be used directly as an if condition.
In this case, c2go also fails to properly translate the NULL initializer for the function pointer.
To Reproduce

#include <stdio.h>

typedef int (*BinaryIntFunc)(int, int);

int main(void) {
    BinaryIntFunc f = NULL;

    if (f) {
        printf("not null\n");
    } else {
        printf("null\n");
    }

    return 0;
}

Generated Go Code

func main() {
        var // Warning (VarDecl): test.c:6 : Cannot casting {NullPointerType * -> BinaryIntFunc}. err = Cannot casting {NullPointerType * -> int (*)(int, int)}. err = Cannot resolve type 'NullPointerType *' : Cannot resolve type 'NullPointerType' : I couldn't find an appropriate Go type for the C type 'NullPointerType'.
        f BinaryIntFunc

        if (func(int32, int32) int32)((BinaryIntFunc(f))) {
                noarch.Printf((&[]byte("not null\n\x00")[0]))
        } else {
                noarch.Printf((&[]byte("null\n\x00")[0]))
        }
        return
}

Observed Behavior
The generated Go code fails to compile:

# command-line-arguments
./test.go:169:5: non-boolean condition in if statement

The problematic code is:

if (func(int32, int32) int32)((BinaryIntFunc(f))) {

The condition should instead be translated as an explicit nil check, for example:

if f != nil {

or an equivalent check using the generated function pointer type.
Additional Example
A similar issue occurs when applying logical NOT to a function pointer condition:

#include <stdio.h>

int main(void) {
    int (*func_ptr)(int, int) = NULL;

    if (!func_ptr) {
        printf("null\n");
    }

    return 0;
}

The generated Go code:

func main() {
    var func_ptr func(int32, int32) int32
    if noarch.NotFunc_int32 , int32__int32_(func_ptr) {
        noarch.Printf((&[]byte("null\n\x00")[0]))
    }
    return
}

and fails to compile with:

syntax error: unexpected {, expected := or = or comma
syntax error: unexpected }, expected expression

The condition should be translated as an explicit nil check, for example:

if func_ptr == nil {

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions