
Vambola Kotkas wrote:
Wave Driver C++ preprocessor seems quite useful tool to see what happens with most macros. Unfortunatelly it needs some debugging before it can be used to preprocess real code. For example it refuses (unneccessarily) to process sometimes.
Silly example 1: #if __LINE__ == 11112223334 #pragma message( "Huh!" ) #endif Result: test.cpp(1): error: ill formed integer literal or integer constant too large: 11112223334.
None of the available wave flags did seemingly help. Not that i need huge integers, however boost sometimes does have way bigger ones so it must be legal? MS Visual C++ 7.1 processes constants like 18446744073709551615 without any noise. See ... 1.33.0 boost/cstdint.hpp line(263): # if ULONG_MAX == 18446744073709551615 // 2**64 - 1
It's not legal for 32 bit systems. Either flag the 11112223334 with the LL suffix (and the --long_long command line option) or you are out of luck with Wave. At least as long the code is not hidden inside a non-evaluated #if/#endif block. I've fixed Wave after 1.33.0 to accept large numbers in non-evaluated #if expressions, just to allow to compile Boost.
Silly example 2: #define SHOW2(x) #x #define SHOW(x) SHOW2(Number is:##x) #pragma message( SHOW(__LINE__)) Result: test.cpp(3): error: pasting the following two tokens does not give a valid preprocessing token: ":" and "__LINE__"
Concatenating two unrelated tokens isn't allowed by the C++ Standard. If you really need this just provide the --variadics command line option, which will enable certain C99 features in C++ (variadics, token concatination of unrelated tokens etc.)
Maybe its buggy and MS made its preprocessor too lousy there ... just for reference Visual C++ 7.1 preprocess result:
Yes, the MSVC preprocessor is lousy.
Side question: How to force wave to use full paths in #line directives? Larger projects may contain similarily named files and people usually have multiple versions of their own software, nothing to talk of libraries and SDK-s.
Wave does use full paths in #line directives as long as the corresponding files are not in the directory of the main file.
Silly thing 2 can be transformed into Working thing 2: #define SHOW2(x) #x #define SHOW(x) SHOW2(x) #pragma message("Number is:" SHOW(__LINE__)) Wave produces same output as VC++ 7.1 then: #line 3 "test.cpp" #pragma message("Number is:" "3")
What's silly here?
Finally ... fair test for preprocessor is if it preprocesses its own code. That makes wave to crash with "unexpected exception caught." Various sets of -P and -D options make it to crash in various places. I did not manage to find a good set of options so it does not crash. How to compile debug version of wave with vc7.1?
bjam "-sBUILD=<debug>" ... ?
Without debugging it is hard to further track down what is going on there. I tried the wave in boost 1.33.0.
Frankly speaking, I haven't done this for a long time. So I tried today and got several errors/warnings reported by Wave (which I have to investigate further), but I didn't get any segfault! I'll report on this list with my findings. Could you please elaborate on which compiler you used to generate Wave, which command line options did you use? Regards Hartmut

On 12/4/05 11:59 AM, "Hartmut Kaiser" <hartmut.kaiser@gmail.com> wrote:
Vambola Kotkas wrote:
Wave Driver C++ preprocessor seems quite useful tool to see what happens with most macros. Unfortunatelly it needs some debugging before it can be used to preprocess real code. For example it refuses (unneccessarily) to process sometimes.
Silly example 1: #if __LINE__ == 11112223334 #pragma message( "Huh!" ) #endif Result: test.cpp(1): error: ill formed integer literal or integer constant too large: 11112223334.
None of the available wave flags did seemingly help. Not that i need huge integers, however boost sometimes does have way bigger ones so it must be legal? MS Visual C++ 7.1 processes constants like 18446744073709551615 without any noise. See ... 1.33.0 boost/cstdint.hpp line(263): # if ULONG_MAX == 18446744073709551615 // 2**64 - 1
It's not legal for 32 bit systems. Either flag the 11112223334 with the LL suffix (and the --long_long command line option) or you are out of luck with Wave. At least as long the code is not hidden inside a non-evaluated #if/#endif block. I've fixed Wave after 1.33.0 to accept large numbers in non-evaluated #if expressions, just to allow to compile Boost. [TRUNCATE]
Maybe one day we could use some sort of bignum class to hold preprocessor numbers. I'm guessing that you currently base the "number too large" errors by trying to load the number into a (built-in) numeric variable. The problem is that it won't work for cross-compilers where the compiling computer's number sizes are smaller than the number sizes on the target computer. -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com

Daryle Walker wrote:
It's not legal for 32 bit systems. Either flag the 11112223334 with the LL suffix (and the --long_long command line option) or you are out of luck with Wave. At least as long the code is not hidden inside a non-evaluated #if/#endif block. I've fixed Wave after 1.33.0 to accept large numbers in non-evaluated #if expressions, just to allow to compile Boost. [TRUNCATE]
Maybe one day we could use some sort of bignum class to hold preprocessor numbers. I'm guessing that you currently base the "number too large" errors by trying to load the number into a (built-in) numeric variable. The problem is that it won't work for cross-compilers where the compiling computer's number sizes are smaller than the number sizes on the target computer.
Yes, it currently depends on the size of a 'long' for the platform Wave was compiled for. But the whole expression arithmetic is very localised to a single class, so that changing the implementation isn't an issue at all. Are there any plans to add a bignum class to Boost? Regards Hartmut

Are there any plans to add a bignum class to Boost?
I tried to do this and submitted 2 versions so people could criticize it and always had to fight with people that demanded that the library has to be as fast as the fastest open source implementation (in this case, GMP.) I can not claim that speed, but I implemented a really fast big number library using assembler only on the critical paths on the most CPU demanding instructions. That was not enough for some boost-ers. Regards, Lucas Galfaso
Regards Hartmut
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Lucas Galfaso wrote:
Are there any plans to add a bignum class to Boost?
I tried to do this and submitted 2 versions so people could criticize it and always had to fight with people that demanded that the library has to be as fast as the fastest open source implementation (in this case, GMP.) I can not claim that speed, but I implemented a really fast big number library using assembler only on the critical paths on the most CPU demanding instructions. That was not enough for some boost-ers.
Could you point me to this library, please? I'ld like to try to put it into Wave to support cross compilation and/or configurable precision support. Regards Hartmut

Seems that the version of wave in current boost 1.33.1 release candidate crashes and hangs lot less than the one in 1.33.0 release, thanks. What is great it does not crash or refuse on its own code anymore. As for big integers ... i am no expert, but maybe it is not best idea to use implementations that contain assembler parts in cross-platform libraries like boost. 15 years ago it was very common to use manually optimized code in critical parts, these days however C++ compilers do optimizations all better and better. Got pair of questions too but no need to answer if no and no. ;-) Is there simple way to setup bjam to preprocess the whole boost library with wave? So to get the impression how good it is. Is there an option to direct the output into *.i files instead of stdout? I currently do it with -o option just that .i file seems to be default for most other C++ preprocessors. Getting slightly bored to type twice. Thanks again.

Vambola Kotkas wrote:
Is there simple way to setup bjam to preprocess the whole boost library with wave?
No. Any non-trivial use of wave will involve system-headers, meaning wave needs to be told system include paths and predefined macros, to effectively emulate the system compiler (or, the compiler that bjam would use on that system). The synopsis project (http://synopsis.fresco.org/) uses wave in its development branch as preprocessor, and it provides some code to query the necessary info from available compilers, so wave is able to process system headers without any additional manual intervention. Regards, Stefan

Vambola Kotkas wrote:
As for big integers ... i am no expert, but maybe it is not best idea to use implementations that contain assembler parts in cross-platform libraries like boost. 15 years ago it was very common to use manually optimized code in critical parts, these days however C++ compilers do optimizations all better and better.
I agree with that. But as soon a bignum library will be available in Boost I'll try to integrate it to allow cross compilation etc.
Is there an option to direct the output into *.i files instead of stdout? I currently do it with -o option just that .i file seems to be default for most other C++ preprocessors. Getting slightly bored to type twice.
;-) The answer is no. But nothing prevents you from changing the wave driver and add a -E option (or something similar) which instructs wave to always output the preprocessed tokens to a file names *.i. But if this is of general interest I can do that as well, it's not terribly difficult to implement in the end. Regards Hartmut

Hartmut Kaiser wrote
Is there an option to direct the output into *.i files instead of stdout? I currently do it with -o option just that .i file seems to be default for most other C++ preprocessors. Getting slightly bored to type twice.
;-)
The answer is no. But nothing prevents you from changing the wave driver and add a -E option (or something similar) which instructs wave to always output the preprocessed tokens to a file names *.i. But if this is of general interest I can do that as well, it's not terribly difficult to implement in the end.
This might be useful to have, especially if/when BBv2 adds preprocessor support that allows you to specify a different preprocessor to the compiler being used, so you could compile using wave as the PP and VC as the compiler. - Reece

Reece Dunn wrote:
The answer is no. But nothing prevents you from changing the wave driver and add a -E option (or something similar) which instructs wave to always output the preprocessed tokens to a file names *.i. But if this is of general interest I can do that as well, it's not terribly difficult to implement in the end.
This might be useful to have, especially if/when BBv2 adds preprocessor support that allows you to specify a different preprocessor to the compiler being used, so you could compile using wave as the PP and VC as the compiler.
Done. I added the -E option which makes the wave driver redirect the generated output to a file named after the input file, changing the extension to '.i'. Regards Hartmut

On 12/7/05, Hartmut Kaiser <hartmut.kaiser@gmail.com> wrote:
Done. I added the -E option which makes the wave driver redirect the generated output to a file named after the input file, changing the extension to '.i'.
Standard behavior for compilers on UNIX is to emit preprocessed output to stdout with just "-E". Output may be sent to a file (regardless of the filename suffix, though clearly ".i" is the popular convention) by passing an "-o" argument. -- Caleb Epstein caleb dot epstein at gmail dot com

Caleb Epstein wrote:
Standard behavior for compilers on UNIX is to emit preprocessed output to stdout with just "-E". Output may be sent to a file (regardless of the filename suffix, though clearly ".i" is the popular convention) by passing an "-o" argument.
Sure, this is corret for the compiler interface. If you look at the standalone cpp preprocessor you'll notice, that the default is to output anything to stdout, supporting the -o option to specify an output file. Wave follows this convention. The -E option I've just added is a helper only and does not interfere with other options at all. Just don't use it if you don't like it... (BTW: you can specify the -E option to cpp as well, but it essentially has no effect there). Regards Hartmut

Hartmut Kaiser wrote:
Lucas Galfaso wrote:
Are there any plans to add a bignum class to Boost?
I tried to do this and submitted 2 versions so people could criticize it and always had to fight with people that demanded that the library has to be as fast as the fastest open source implementation (in this case, GMP.) I can not claim that speed, but I implemented a really fast big number library using assembler only on the critical paths on the most CPU demanding instructions. That was not enough for some boost-ers.
Could you point me to this library, please? I'ld like to try to put it into Wave to support cross compilation and/or configurable precision support.
IMO, you do not need an arbitrary precision integer. All you need is a fixed precision integer (64, 128 or 256 bits). That is a lot faster to operate on. There are lots of such libraries and it's easy to write one. Surely, you do not need to compute things like PI to a million decimal places ;-) Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

Joel de Guzman wrote:
Could you point me to this library, please? I'ld like to try to put it into Wave to support cross compilation and/or configurable precision support.
IMO, you do not need an arbitrary precision integer. All you need is a fixed precision integer (64, 128 or 256 bits). That is a lot faster to operate on. There are lots of such libraries and it's easy to write one. Surely, you do not need to compute things like PI to a million decimal places ;-)
Do you have something particular in mind? Regards Hartmut

Hartmut Kaiser wrote:
Joel de Guzman wrote:
Could you point me to this library, please? I'ld like to
try to put it into
Wave to support cross compilation and/or configurable
precision support.
IMO, you do not need an arbitrary precision integer. All you need is a fixed precision integer (64, 128 or 256 bits). That is a lot faster to operate on. There are lots of such libraries and it's easy to write one. Surely, you do not need to compute things like PI to a million decimal places ;-)
Do you have something particular in mind?
gcc uses some special doubleword arithmetic using a pair of values for this case. FWIW, Stefan

Stefan Seefeld wrote:
Hartmut Kaiser wrote:
Joel de Guzman wrote:
Could you point me to this library, please? I'ld like to
try to put it into
Wave to support cross compilation and/or configurable
precision support.
IMO, you do not need an arbitrary precision integer. All you need is a fixed precision integer (64, 128 or 256 bits). That is a lot faster to operate on. There are lots of such libraries and it's easy to write one. Surely, you do not need to compute things like PI to a million decimal places ;-)
Do you have something particular in mind?
gcc uses some special doubleword arithmetic using a pair of values for this case. FWIW,
Exactly. I remember writing such a class. I'll see if I can dig it up. Essentially, it is just a fixed array of N integers. It's quite easy to write one with just a pair of integers but it's equally straightforward to generalize that to N integers. Regards, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net

-----Original Message----- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Joel de Guzman
Exactly. I remember writing such a class. I'll see if I can dig it up. Essentially, it is just a fixed array of N integers. It's quite easy to write one with just a pair of integers but it's equally straightforward to generalize that to N integers.
One thing that matters, BTW, is that the standard requires a specific width for all calculations--which definitely matters for bit shifting (which the preprocessor is required to do). IOW, fixed precision bit shifting, at the very least, is required. If a literal (or value for that matter) is too big for 'unsigned long' or 'long' in current C++ or 'unsigned long long' or 'long long' in C, it is undefined behavior. Supporting it is not a good idea. IMO, it is just the beginning of non-standard extensions. For the purpose of cross-compiling, I don't have a problem with an option to specify the width. User's can then explicitly lie if they need to. IMHO, it is in the community's ultimate best interest for preprocessors and compilers to be as *un-permissive* as possible. Compiler permissiveness and language extensions are a huge barrior to portability. Wave should reject any translation unit that exhibits realistically detectable undefined behavior. If there is something that should be specified differently than it is in current C++ or C, that's a problem with the language (not the implementation) that should be handled by those responsible for defining the language--which is the respective standards committees, not implementors. Regards, Paul Mensonides
participants (9)
-
Caleb Epstein
-
Daryle Walker
-
Hartmut Kaiser
-
Joel de Guzman
-
Lucas Galfaso
-
Paul Mensonides
-
Reece Dunn
-
Stefan Seefeld
-
Vambola Kotkas