SQLite Forum

Weird warning on the Xcode/OSX
Login

Weird warning on the Xcode/OSX

(1) By oneeyeman on 2020-08-22 18:51:06 [link] [source]

Hi, ALL, I understand that this will not be fixed (from the previous discussion), but I'm just curious for the reason.

When compiling my code that uses SQLite3 inside the Xcode, I see a following warning (among the others):

Ambiguous expansion of macro MIN Ambiguous expansion of macro MAX

Does this mean that SQLite3 provides its own implementation of them?

Thank you.

(2) By Larry Brasfield (LarryBrasfield) on 2020-08-22 19:37:22 in reply to 1 [link] [source]

Both MIN and MAX are #define'd within sqlite3.c, but each #define is protected with an #ifndef construct to avoid redundant (and usually error producing) redefinition of the macro(s). Hence, there is something more interesting going on than you have supposed. I have no clue as to what it is, being limited to the few facts you provided.

(3) By Richard Hipp (drh) on 2020-08-22 19:38:21 in reply to 1 [link] [source]

There is the following:

But those definitions are private to SQLite (they are not part of the public "sqlite3.h" interface). So I'm not sure why you would be hitting them or why that would be causing problems.

(4.2) By Keith Medcalf (kmedcalf) on 2020-08-22 19:47:56 edited from 4.1 in reply to 1 [link] [source]

Ambiguous expansion of a macro means that the expansion results in ambiguous code.

This is quite independent of who declared the macro's. Whoever provided the macro's provided macro's which expand to ambiguous code.

Perhaps Xcode's (or some other thing you are including) is providing macro definitions for MIN and MAX that result in ambiguous code.

In order to find out you would need to find the spot at which the complaint is made, find out what the contents of the macro being complained about it as the time that the complaint is made, and then find out who made that declaration. Jolly good compilers will give you all that information at once in the error message.

I have no idea if Xcode is a Jolly Good compiler or not, but it sounds from the question that you are asking that it does not fall into that category and is basically giving you the equivalent of a 1980's style "how?" error message.

(5) By oneeyeman on 2020-08-22 19:51:41 in reply to 3 [link] [source]

Hi, Richard,

Clicking on the warning itself reveals:

line 27134 of sqlite3.c: if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){

Clicking on "Expanding this definition of MAX": line 218 of /usr/include/sys/param.h (MacOS 10.13):

#define MAX(a,b) (((a)>(b))?(a):(b))

Clicking on the line: "Other definition of MAX":

line 13457 of sqlite3.c:

define MAX(A,B) ((A)>(B)?(A):(B))

(6) By Larry Brasfield (LarryBrasfield) on 2020-08-22 19:55:31 in reply to 1 [link] [source]

Expanding on Keith's observation: You could conveniently confirm his hypothesis by inserting these lines at the top of sqlite3.c: #undef MIN #undef MAX . If that eliminates the warning, then a careful look at the expansion without those insertions is warranted. C compilers usually have an option, (typically -E), to produce preprocessed output, where you can see the macro expansions. Then you can at least see the problematic expansion. It will be more of a challenge to discover where the #define is located, but the -E output will also show you what files were made part of the compilation unit. (There will be quite a few, but only a subset of them will #define MIN and MAX.)

(7) By Larry Brasfield (LarryBrasfield) on 2020-08-22 20:03:17 in reply to 5 [link] [source]

There is nothing wrong with either of those macro definitions. I think you have to see how line 27134 of sqlite3.c is actually expanded. Either #define produces sensible C code that any C compiler should accept with any yapping.

(8) By oneeyeman on 2020-08-22 20:13:56 in reply to 7 [source]

Hi, Larry,

I believe that expansion goes to the system one, according to my post. The inclusion of the param.h happens here:

sqlite3.c@ 31564:

#if SQLITE_ENABLE_LOCKING_STYLE /* # include <sys/ioctl.h> */

include <sys/file.h>

include <sys/param.h>

#endif /* SQLITE_ENABLE_LOCKING_STYLE */

I have no idea what the #if condition should or shouldn't do. But I guess it is defined in my build...

Thank you.

(9) By TripeHound on 2020-08-22 21:25:06 in reply to 1 [link] [source]

What version of sqlite3.c are you using? Can you check if it has guards around the definitions of MIN and MAX? At line 14247 in my copy (v3.33.0), there's:

#ifndef MIN
# define MIN(A,B) ((A)<(B)?(A):(B))
#endif
#ifndef MAX
# define MAX(A,B) ((A)>(B)?(A):(B))
#endif

That came from sqliteInt.h. There's a similar, guarded definition at line 166006 (that seems to come from fts3Int.h) and another at 187836 (that comes from rtree.c). The latter both use x and y instead of A and B. Finally, at line 207899 (originating from fts5.c), there is what at first glance appears to be an unguarded pair of definitions:

#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX(x,y) (((x) > (y)) ? (x) : (y))

but there's a #ifndef SQLITE_AMALGAMATION wrapping the section they're in, which I ass.u.me means they'll be excluded when compiling sqlite3.c (but does this mean they could clash with a prior definition if fts5.c is compiled outside the amalgamation?)

(10) By Adrian Ho (lexfiend) on 2020-08-23 10:59:35 in reply to 1 [link] [source]

That's likely the Xcode IDE trying to be helpful, and getting it wrong.

To be sure, run the following command to see if the compilation itself is tossing out any warnings:

clang -Wall -c sqlite3.c -o sqlite3.o
On macOS Catalina, the above compiles correctly with no warnings.

(11) By oneeyeman on 2020-08-23 16:47:05 in reply to 10 [link] [source]

@AdrianHo,

Right on.

Doing this from the Terminal with that command doesn't produce any warnings. Does anybody know how do I see the command Xcode uses to compile the source?

Thank you.

(12) By sbooth on 2020-08-24 12:01:01 in reply to 11 [link] [source]

To see the commands issued by Xcode, go to the Report Navigator (Command-9), find the latest build command, and click the expansion icon next to to the entry called "Compile sqlite3.c".

In my Swift package the (abbreviated) build command is:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x c -target x86_64-apple-macos10.12 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -std=gnu11 -fmodules -gmodules -fmodules-cache-path=/xxx/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/xxx/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -Wnon-modular-include-in-framework-module -Werror=non-modular-include-in-framework-module -fmodule-name=yyy -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-float-conversion -Wno-non-literal-null-conversion -Wno-objc-literal-conversion -Wno-shorten-64-to-32 -Wpointer-sign -Wno-newline-eof -DSWIFT_PACKAGE -DDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_OMIT_DECLTYPE=1 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_OMIT_SHARED_CACHE=1 -DSQLITE_USE_ALLOCA=1 -DSQLITE_OMIT_DEPRECATED=1 -DSQLITE_ENABLE_FTS5=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_SNAPSHOT=1 -DSQLITE_ENABLE_JSON1=1 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -g -Wno-sign-conversion -Wno-infinite-recursion -Wno-comma -Wno-block-capture-autoreleasing -Wno-strict-prototypes -Wno-semicolon-before-method-body

and I see the same warnings:

/xxx/Sources/sqlite3.c:28742:25: warning: ambiguous expansion of macro 'MAX' [-Wambiguous-macro]
          szBufNeeded = MAX(e2,0)+(i64)precision+(i64)width+15;
                        ^
In module 'Darwin' imported from /xxx/Sources/sqlite3.c:1083:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/usr/include/sys/param.h:218:9: note: expanding this definition of 'MAX'
#define MAX(a, b) (((a)>(b))?(a):(b))

sys/param.h contains the block:

/* Macros for min/max. */
#ifndef MIN
#define MIN(a, b) (((a)<(b))?(a):(b))
#endif /* MIN */
#ifndef MAX
#define MAX(a, b) (((a)>(b))?(a):(b))
#endif  /* MAX */

so the declarations there have proper guards. It seems possible this is a clang issue.

(13) By Larry Brasfield (LarryBrasfield) on 2020-08-24 12:15:56 in reply to 12 [link] [source]

I wonder if the different possible expansions are being compared. Most of the definitions have extraneous parentheses around the condition in that ternary expression.

(14) By oneeyeman on 2020-08-24 14:08:54 in reply to 12 [link] [source]

@sbooth, Good - it means I'm not the only one who sees them (on Xcode). Except I'm not on Swift - I'm doing Objective-C stuff.

I think the test I did producing sqlite3.o is not really accurate - "Wall" is not turning on "all" warnings (if my memory serves me right).

So apparently it is Xcode/clang thing and we have to live with that. ;-)

Thank you.