-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GDShader has several syntax issues when you #define
function-like macros
#96253
Comments
Interestingly, I also found 2 more GDShader preprocessor behaviors that differ from C/GLSL. The preprocessor in C and GLSL:
The preprocessor in GDShader:
Test 5: does it have no macro recursion issues? #define selfCall(x) x(x)+x(X)
selfCall(selfCall);
// C does: selfCall(selfCall)+selfCall(X);
// GLSL does: selfCall(selfCall) + selfCall(X);
// GDShader reports error: Macro expansion limit exceeded. Test 6: does it expand the macro itself before its arguments? #define Twice(x) x ## x
#define kJoin(x) k ## x(1)
kJoin(Twice(j));
// C does: kTwice(j)(1);
// GLSL does: kTwice(j) (1);
// GDShader differs: kjj(1) ; // also kjj(1) even if we #define kJoin(x) above Twice(x) C tests: |
Found another inconsistency. Not sure if it's to be considered a bug, should I open a new issue? In GDShader In any case, I'm surprised things like functions work at all. I think dealing with integers and booleans would be enough. EDIT: In any case, this feels like an oversight, is this intended? |
Good findings! I've addressed issues 1-3 in #96327 4 - expansion of macros in strings): 5 - recursion: 6 - expansion order: 7 - function calls in #if directives: |
I found another issue related to macro expansion and listed it above. Issue 8: Replace macro arguments all at once, not sequentiallyIf macro arguments are replaced sequentially, then an argument containing a parameter name that is yet to be replaced will cause that replacement to incorrectly affect it again. In the code below, the 1st expansion argument (assigned to parameter
shader_type spatial;
#define f(a, b, c) a+b*c
f(b,2,b)
$
// C does: b+2*b
// GLSL does: b + 2 * b
// GDShader differs: 2+2*b |
I brought up this Issue in the 2024-09-03 Rendering Meeting, these are the key points:
Conclusions for me are:
Update: I fixed 5,6 and 8 in my PR above |
Found another minor inconsistency. Unsure if we should bother with it, but reporting it here at least for the memes. Issue 9: Forbid defining or undefining a macro named "defined"C and GLSL both disallow using the name of the preprocessor function
shader_type spatial;
#define f(define, defined) g(define, defined)
#define defined(defined) h(defined)
#define define(define) i(define)
#if defined(defined)
#define test is_defined
#endif
test
f(1,2)
defined(1)
define(1) C:
Interestingly, they seem to allow
|
Tested versions
System information
Godot v4.3.stable (77dcf97) - Freedesktop SDK 23.08 (Flatpak runtime) - X11 - Vulkan (Forward+) - integrated Intel(R) HD Graphics 5500 (BDW GT2) - Intel(R) Core(TM) i5-5300U CPU @ 2.30GHz (4 Threads)
Issue description
I've identified several issues when defining macros with arguments in GDShader preprocessor.
Issues are confirmed by comparing expected behavior to GLSL (ShaderToy / glslang) and C Preprocessor (GCC).
Issue 1: Report duplicate macro parameters
GLSL in ShaderToy gives the following error in this case:
In the C preprocessor (GCC) the error looks like this:
Issue 2: Leave function-like macro name alone when used without parentheses
There is another inconsistency between GDShader and GLSL/C preprocessors.
If you define a function-like macro with parentheses, GLSL and C will still allow that name to appear without parentheses and leave it alone (it won't try to expand it). GDShader, however, doesn't do this, and its way of handling it causes issues (not entirely sure to what extent, but I found a very weird issue in my tests).
Issue 3: Support function-like macros with zero parameters
GLSL replaces
macroName()
(no arguments, but including the parentheses) when it's defined with parentheses, and justmacroName
if it's defined without parentheses. I tested the C preprocessor (GCC) and it works the same way.This should be allowed in GDShader as well.
Issue 4: Do not expand macro parameters defined inside strings
Strings are not supported in GLSL, but since they are going to be supported in GDShader, their handling in the preprocessor should match C. I assume it's still an issue, but note that I didn't test this against master (please confirm).
Parameters in macros are replaced wherever they appear in their definition. But if they appear inside a string, it should of course not be replaced. That's how the C preprocessor handles it.
Other issues: see comments below
Steps to reproduce
Hint: Using an invalid token like
$
logs the preprocessor output (even on otherwise "valid" code) to help testing.issue1.gdshader
issue2.gdshader
issue3.gdshader
issue4.gdshader
Minimal reproduction project (MRP)
N/A
The text was updated successfully, but these errors were encountered: