occa icon indicating copy to clipboard operation
occa copied to clipboard

problems with sizeof(T) in preprocessor #if condition

Open pdhahn opened this issue 7 months ago • 6 comments

Things like

#if sizeof(unsigned long) == sizeof(int)

in an OKL file cause an error in translation

../../testing/test1.okl:123:12: Error: Unable to form an expression
#if sizeof(unsigned long) == sizeof(int)

On the other hand, things like

#if sizeof(short) < sizeof(int)

seem to pass translation OK, yet do not work properly (are not evaluated correctly).

I am reporting this for libocca commit 65efd39c1fd1fe1de0317f4ed5b176bd142303dc. My platform is Linux Mint 21 with g++ 11.4.

pdhahn avatar Jul 11 '25 04:07 pdhahn

Yes, I can reproduce this issue. For me both #if sizeof(unsigned long) == sizeof(int) and #if sizeof(short) < sizeof(int) trigger Error: Unable to form an expression error.

PS: sizeof(short) parses without an error and it is unsigned int which issues an error.

thilinarmtb avatar Jul 14 '25 18:07 thilinarmtb

Seems like the pre-processor eats out #if and then the tokenizer passes the following token sequence to the parser incase of #if sizeof(unsigned int) == sizeof(int):

Token: sizeof, type = 32768
Token: (, type = 32768
Token: 0, type = 16384
Token: 0, type = 16384
Token: ), type = 32768
Token: ==, type = 32768
Token: sizeof, type = 32768
Token: (, type = 32768
Token: 0, type = 16384
Token: ), type = 32768

The error is due to the two 0, 0 after the first sizeof. Either way, it is not doing the right thing.

thilinarmtb avatar Jul 15 '25 17:07 thilinarmtb

Okay issue seems to be the following. Whenever a #if is encountered during pre-processing, occa tries to evaluate it using processIf(). This function subsequently calls lineIsTrue().

In this loop inside lineIsTrue() basically substitutes 0 for all the non-identifiers. That is how we get zeros inside sizeof.

thilinarmtb avatar Jul 15 '25 19:07 thilinarmtb

Feels like we shouldn't evaluate these pre-processor expressions and just pass them to the backend source file unmodified. That way the actual backend compiler could evaluate them accurately.

OCCA anyway can't evaluate things like sizeof(long) during OKL to backend source translation as it doesn't know these values.

thilinarmtb avatar Jul 15 '25 19:07 thilinarmtb

Good analysis.

I agree with you -- they ought to be passed through to the backend compiler.

pdhahn avatar Jul 15 '25 23:07 pdhahn

This is a related issue: https://github.com/libocca/occa/issues/180.

thilinarmtb avatar Oct 07 '25 16:10 thilinarmtb