floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.53k stars 467 forks source link

error: expected '(' for function-style cast or type construction, while using SG_RANGE on MacOS using c++ #1035

Closed SethArchambault closed 2 months ago

SethArchambault commented 2 months ago

I get the following error:

includes/sokol_gl.h:3245:36: error: expected '(' for function-style cast or type construction
    img_desc.data.subimage[0][0] = SG_RANGE(pixels);
                                   ^~~~~~~~~~~~~~~~
includes/sokol_gfx.h:1502:29: note: expanded from macro 'SG_RANGE'
#define SG_RANGE(x) sg_range{ &x, sizeof(x) }

https://github.com/floooh/sokol/blob/c2bb83f0b35e09d97a354b5f4cf4c3df783c4193/sokol_gfx.h#L1501-L1507

I'm using c++ without -std=cpp20 and I had to add a ! to reverse this #if in order to get this to work:

#if !defined(__cplusplus)
#define SG_RANGE(x) sg_range{ &x, sizeof(x) }
#define SG_RANGE_REF(x) sg_range{ &x, sizeof(x) }
#else
#define SG_RANGE(x) (sg_range){ &x, sizeof(x) }
#define SG_RANGE_REF(x) &(sg_range){ &x, sizeof(x) }
#endif

Wondering if that got switched accidentally, or if I'm missing something!

floooh commented 2 months ago

That is very strange, since I'm also mainly on macOS. The SG_RANGE definition is correct, e.g. this should be used on C++:

 #define SG_RANGE(x) sg_range{ &x, sizeof(x) } 
 #define SG_RANGE_REF(x) sg_range{ &x, sizeof(x) } 

Can you check what happens when you paste the macro content into your code instead? E.g.:

img_desc.data.subimage[0][0] = sg_range{ &pixels, sizeof(pixels) };

PS: here's some test code in Godbolt with the SG_RANGE C++ macro:

https://www.godbolt.org/z/fdn73oh8j

floooh commented 2 months ago

Aha. It's an error for std=c++98, but not for std=c++11 or later.

Do you explicitly compile as c++98? Because AFAIK most C compilers have switched to a later version by default.

You can fix this problem for C++98 by using this instead:

img_desc.data.subimage[0][0] = { &pixels, sizeof(pixels) };

...but I don't want to change this in sokol_gfx.h (IIRC the form sg_range{...} was a later fix requested by somebody else, but I'd need to dig into the git history for more details).

In my own C++ code I wouldn't notice this because most of the C++ dependencies which require me to use C++ in the first place require at least C++11 or C++14, and in one case even C++17.

SethArchambault commented 2 months ago

@floooh Wow, thanks for the speedy response!

Yep that seems to be the issue, unfortunately I can't use the std command currently, because of the objective c requirement (created by the inclusion of sokol.m).

So here's what I'm running, notice no -std is included:

clang++ -DUSE_DBG_UI temp/main.o libs/libimgui.a libs/libdbgui.a src/macos_platform.cpp libs/sokol.m -o temp/main -DSOKOL_METAL -fobjc-arc -I includes -framework Metal -framework Cocoa -framework MetalKit -framework Quartz -framework AudioToolbox -g -fsanitize=address -fno-sanitize-recover=all -static-libsan -Werror -Wall -Wextra -Wshadow -Wconversion -Wno-unused-variable -Wno-unused-parameter -Wno-deprecated-declarations -Wno-unused-value -Wno-unused-function -Wno-missing-field-initializers -Wno-implicit-float-conversion -ferror-limit=4 -O0

And here's the errors, notice they're from sokol_gl.h, which would be more work to manually change:

includes/sokol_gl.h:3245:36: error: expected '(' for function-style cast or type construction
    img_desc.data.subimage[0][0] = SG_RANGE(pixels);
                                   ^~~~~~~~~~~~~~~~
includes/sokol_gfx.h:1502:29: note: expanded from macro 'SG_RANGE'
#define SG_RANGE(x) sg_range{ &x, sizeof(x) }
                    ~~~~~~~~^
In file included from src/macos_platform.cpp:32:
includes/sokol_gl.h:3298:40: error: expected '(' for function-style cast or type construction
                shd_desc.vs.bytecode = SG_RANGE(_sgl_vs_bytecode_metal_macos);
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
includes/sokol_gfx.h:1502:29: note: expanded from macro 'SG_RANGE'
#define SG_RANGE(x) sg_range{ &x, sizeof(x) }
                    ~~~~~~~~^
In file included from src/macos_platform.cpp:32:
includes/sokol_gl.h:3299:40: error: expected '(' for function-style cast or type construction
                shd_desc.fs.bytecode = SG_RANGE(_sgl_fs_bytecode_metal_macos);
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
includes/sokol_gfx.h:1502:29: note: expanded from macro 'SG_RANGE'
#define SG_RANGE(x) sg_range{ &x, sizeof(x) }
                    ~~~~~~~~^
In file included from src/macos_platform.cpp:32:
includes/sokol_gl.h:3302:40: error: expected '(' for function-style cast or type construction
                shd_desc.vs.bytecode = SG_RANGE(_sgl_vs_bytecode_metal_ios);
                                       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
includes/sokol_gfx.h:1502:29: note: expanded from macro 'SG_RANGE'
#define SG_RANGE(x) sg_range{ &x, sizeof(x) }

If I go and add -std=c++11 like this:

clang++ -std=c++11 -DUSE_DBG_UI temp/main.o libs/libimgui.a libs/libdbgui.a src/macos_platform.cpp libs/sokol.m -o temp/main -DSOKOL_METAL -fobjc-arc -I includes -framework Metal -framework Cocoa -framework MetalKit -framework Quartz -framework AudioToolbox -g -fsanitize=address -fno-sanitize-recover=all -static-libsan -Werror -Wall -Wextra -Wshadow -Wconversion -Wno-unused-variable -Wno-unused-parameter -Wno-deprecated-declarations -Wno-unused-value -Wno-unused-function -Wno-missing-field-initializers -Wno-implicit-float-conversion -ferror-limit=4 -O0 

I get this:

error: invalid argument '-std=c++11' not allowed with 'Objective-C'

Note that this error happens if I use -std= at all, including -std=c++98..

So to recap:

Questions:

Appreciate the response!

floooh commented 2 months ago

Hmm interesting, I guess I've not been running into those issues for the "build without a build system" instructions (https://github.com/floooh/sokol-samples?tab=readme-ov-file#how-to-build-without-a-build-system) because this only uses C examples.

One thing you could try is renaming the sokol.m file as sokol.mm (which is Objective-C++ instead of Objective-C). Clang might then accept the -std=c++11 command line arg because all input files are C++.

(...or describe the build with cmake, this properly supports mixed C and C++ projects)

SethArchambault commented 2 months ago

Yes! Just renaming sokol.m to sokol.mm made it work! Thanks!

SethArchambault commented 2 months ago

Updated the title so it's easier for others to find if they have the same issue, thanks again!