Yep, it's string concatenation, and it's ANSI C as per 5.1.1.2. We use this idiom in other parts of the RTS.
Cheers, Edward Excerpts from Simon Peyton-Jones's message of Wed Sep 04 02:22:48 -0700 2013: > IF_DEBUG(linker, debugBelch("Checking whether to unload " FMT_PATH "\n", > > doesn't that expand to > > IF_DEBUG(linker, debugBelch("Checking whether to unload " "%S" "\n", > > What does the C compiler make of three strings in a row? Does it > automatically concatenate them? Is that ANSI C? > > S > > | -----Original Message----- > | From: ghc-devs [mailto:ghc-devs-boun...@haskell.org] On Behalf Of Edward > | Z. Yang > | Sent: 04 September 2013 10:15 > | To: Jost Berthold > | Cc: ghc-devs > | Subject: Re: RE: More windows woe > | > | I think this is reasonable, with the added caveat that > | the macros should be placed in includes/rts/Linker.h, because that is > | where pathchar is defined. So how about something like: > | > | diff --git a/includes/rts/Linker.h b/includes/rts/Linker.h > | index e900e85..871b8cd 100644 > | --- a/includes/rts/Linker.h > | +++ b/includes/rts/Linker.h > | @@ -16,8 +16,10 @@ > | > | #if defined(mingw32_HOST_OS) > | typedef wchar_t pathchar; > | +#define FMT_PATH "%S" > | #else > | typedef char pathchar; > | +#define FMT_PATH "%s" > | #endif > | > | /* initialize the object linker */ > | diff --git a/rts/CheckUnload.c b/rts/CheckUnload.c > | index a758b06..8dc8fdc 100644 > | --- a/rts/CheckUnload.c > | +++ b/rts/CheckUnload.c > | @@ -254,7 +254,7 @@ void checkUnload (StgClosure *static_objects) > | > | // Mark every unloadable object as unreferenced initially > | for (oc = unloaded_objects; oc; oc = oc->next) { > | - IF_DEBUG(linker, debugBelch("Checking whether to unload %s\n", > | + IF_DEBUG(linker, debugBelch("Checking whether to unload " > | FMT_PATH "\n", > | oc->fileName)); > | oc->referenced = rtsFalse; > | } > | @@ -290,11 +290,11 @@ void checkUnload (StgClosure *static_objects) > | } else { > | prev->next = oc->next; > | } > | - IF_DEBUG(linker, debugBelch("Unloading object file %s\n", > | + IF_DEBUG(linker, debugBelch("Unloading object file " FMT_PATH > | "\n", > | oc->fileName)); > | freeObjectCode(oc); > | } else { > | - IF_DEBUG(linker, debugBelch("Object file still in use: %s\n", > | + IF_DEBUG(linker, debugBelch("Object file still in use: " > | FMT_PATH "\n", > | oc->fileName)); > | } > | } > | diff --git a/rts/Linker.c b/rts/Linker.c > | index 6490242..4f0a1c4 100644 > | --- a/rts/Linker.c > | +++ b/rts/Linker.c > | @@ -2790,7 +2790,7 @@ unloadObj( pathchar *path ) > | > | initLinker(); > | > | - IF_DEBUG(linker, debugBelch("unloadObj: %s\n", path)); > | + IF_DEBUG(linker, debugBelch("unloadObj: " FMT_PATH "\n", path)); > | > | prev = NULL; > | for (oc = objects; oc; prev = oc, oc = next) { > | > | Excerpts from Jost Berthold's message of Tue Sep 03 12:56:03 -0700 2013: > | > > From: Simon Peyton-Jones <simo...@microsoft.com> > | > > To: "Edward Z. Yang" <ezy...@mit.edu>, Simon Marlow > | > > <marlo...@gmail.com> > | > > Cc: "ghc-devs@haskell.org" <ghc-devs@haskell.org> > | > > Subject: RE: More windows woe > | > > Message-ID: > | > > > | <59543203684b2244980d7e4057d5fbc1485bb...@db3ex14mbxc308.europe.corp.mic > | rosoft.com> > | > > > | > > Content-Type: text/plain; charset="utf-8" > | > > > | > > Simon Marlow: please help! > | > > At the moment windows builds are hosed, which is a Bad Situation. > | > > > | > > Actually it turns out that what want is > | > > > | > > debugBelch("Checking whether to unload %S\n", oc->fileName)); > | > > > | > > That is, use "%S" rather than "%s" as format specifier for wide > | chars. > | > > > | > > Sadly, this works on Windows, but not on Linux: > | > > rts/CheckUnload.c:260:13: > | > > error: format ?%S? expects argument of type ?wchar_t *?, but > | argument 2 has type ?pathchar *? [-Werror=format] > | > > > | > > > | > > So what I need guidance on, please!, is what the approved way to > | deal with this is. I suppose that I could identify each use of %s on a > | filepath and say > | > > > | > > #ifdef mingw32_HOST_OS > | > > debugBelch("Checking whether to unload %S\n", oc->fileName)); > | > > #else > | > > debugBelch("Checking whether to unload %s\n", oc->fileName)); > | > > #endif > | > > > | > > But that seems deeply unsatisfactory doesn't it? > | > > > | > > If not that, then what? > | > > > | > > > | > > Simon > | > > | > Similar code is in place to distinguish between 32-bit and 64-bit > | StgWords: > | > > | > > grep -r -e FMT_Word includes/ > | > includes/stg/Types.h:#define FMT_Word32 "u" > | > includes/stg/Types.h:#define FMT_Word32 "lu" > | > includes/stg/Types.h:#define FMT_Word64 "lu" > | > includes/stg/Types.h:#define FMT_Word64 "llu" > | > includes/stg/Types.h:#define FMT_Word FMT_Word64 > | > includes/stg/Types.h:#define FMT_Word FMT_Word32 > | > > | > and format strings like "blabla " FMT_Word " ..blabla" are used inside > | > rts/. One could do the same for FMT_Path and introduce it where > | required. > | > > | > Maybe this would be acceptable? > | > > | > / Jost > | > > | > | _______________________________________________ > | ghc-devs mailing list > | ghc-devs@haskell.org > | http://www.haskell.org/mailman/listinfo/ghc-devs _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://www.haskell.org/mailman/listinfo/ghc-devs