[Home] [Downloads] [Search] [Help/forum]

Gammon Forum

See www.mushclient.com/spam for dealing with forum spam. Please read the MUSHclient FAQ!

[Folder]  Entire forum
-> [Folder]  Programming
. -> [Folder]  General
. . -> [Subject]  Expression parser
Home  |  Users  |  Search  |  FAQ
Username:
Register forum user name
Password:
Forgotten password?

Expression parser

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Pages: 1 2  3  4  5  

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Mon 13 Sep 2004 10:02 PM (UTC)

Amended on Mon 15 Feb 2010 08:40 PM (UTC) by Nick Gammon

Message
Introduction

I am pleased to present a runtime "expression evaluator" (parser) which is intended to allow you to defer to run-time calculations (like, how many seconds a weapon takes to reach its target).

The intention here is that, rather than hard-coding things like:


  power_of_weapon = str * 3 + dex / 2


... you could put them into "area files" (or the equivalent) and have them evaluated by the MUD server.

This is done by processing a "string" expression (ie. text) and producing a result. The calculations are done using floating-point numbers (doubles) to give maximum accuracy and allow for fractional results.


  Example:  2 + 2
  Result: 4
  
  Example:  log10 (1234)
  Result: 3.09132


The parser builds up results "on the fly" reporting syntax problems by throwing an exception.


  Example: 1 + 3 + )
  exception: Unexpected token: )


Run-time errors (principally "divide by zero") are also thrown as an exception:


  Example: 2 / 0
  exception: Divide by zero




Supported operations

Basic arithmetic: + - / *


  Example: 1000 + 123
  Result: 1123
  
  Example: 44 * 55
  Result: 2420


Expressions are evaluated from left-to-right, with divide and multiply taking precedence over add and subtract.


  Example:  2 + 3 * 6
  Result: 20   (the multiply is done first)


Parentheses can be used to change evaluation order.


  Example:  (2 + 3) * 6
  Result: 30  (the add is done first)


Whitespace is ignored. However 2-character symbols (like ==) cannot have imbedded spaces.



Symbols

The parser supports an unlimited number of named symbols (eg. "str", "dex") which can be pre-assigned values, or assigned during use.


  Example (in C++):
  
    Parser p;   // create a parser instance
    p ["str"] = 55;   // assign value to "str"
    p ["dex"] = 67;   // assign value to "dex"
    double result = p.Evaluate ("str + dex * 2");   // use in expression
    double str = p ["str"];   // retrieve value of "str"
  
  Example: a=42, b=6, a*b
  Result: 252


There are two built-in symbols:


   pi = 3.1415926535897932385
   e  = 2.7182818284590452354  


Symbols can be any length, and must consist of A-Z, a-z, or 0-9, or the underscore character. They must start with A-Z or a-z. Symbols are case-sensitive.



Assignment

Pre-loaded symbols, or ones created on-the-fly, can be assigned to, including the standard C operators of +=, -=, *= and /=.


  Example: a=42, a/=7
  Result: 6
  
  Example: dex = 10, dex += 22
  Result: 32




Comparisons

You can compare values for less, greater, greater-or-equal etc. using the normal C operators.


  Example: 2 + 3 > 6 + 8
  Result: 0  (false)
  
  Example; 2 + 3 < 6 + 8
  Result: 1  (true)


The comparison operators are: <, <=, >, >=, ==, !=

These are a lower precedence than arithmetic, in other words addition and subtraction, divide and multiply will be done before comparisons.



Logical operators

You can use AND, OR, and NOT (using these C symbols: &&, ||, ! )


  Example: a > 4 && b > 8     //  (a > 4 AND b > 8)
  Example: a < 10 || b == 5   //  (a < 10 OR b == 5)
  Example: !(a < 4)           // NOT (a < 4)



These are a lower precedence than comparisons, so the examples above will work "naturally".



Other functions

Various standard scientific functions are supported, by using:

function (argument) or function (argument1, argument2)



Single-argument functions are:

abs acos asin atan atanh ceil cos cosh exp exp floor log log10 sin sinh sqrt tan tanh

These behave as documented for the C runtime library.


  Example: sqrt (64)
  Result: 8


Note that functions like sin, cos and tan use radians, not degrees. To convert to radians, take degrees and multiply by pi / 180 (the value of pi is built-in).


  Example: sin (45 * pi / 180)
  Result: 0.7071


Three other functions which are not directly in the standard library are:

int

int (arg) <-- drops the fractional part


  Example: int (1.2)
  Result: 1

  Example: int (-1.2)
  Result: -1


rand

rand (arg) <-- returns a number in the range 0 to arg

The rand function returns an integer (whole number) result, it will never return arg itself.

eg. rand (3): might return: 0, 1 or 2 (and nothing else)

percent

percent (arg) <-- returns true (1.0) arg % of the time, and false (0.0) the rest of the time

eg. percent (40) will be true 40% of the time


Two-argument functions are:

min (arg1, arg2) <-- returns whichever is the lower
max (arg1, arg2) <-- returns whichever is the higher
mod (arg1, arg2) <-- returns the remainder of arg1 / arg2 - throws an exception if arg2 is zero
pow (arg1, arg2) <-- returns arg1 to the power arg2
roll (arg1, arg2) <-- rolls an arg2-sided dice arg1 times.


  Example: roll (2, 4)  (in other words 2d4)
  Result: 10



If test

Finally you can do "if" tests by using the "if" function.

if (test-value, true-value, false-value)


  Example:  if (a > 5, 22, 33)
  Result: if a > 5, returns 22
          if a <= 5, returns 33


User-written functions

You can easily expand the inbuilt functions by adding more to the source code using the existing ones as an example.




Distinguishing symbols from functions

In order to allow for the case where people may need to use a symbol that happens to be the name of an inbuilt function (eg. abs = 5, pow += 3), the parser distinguishes functions from symbols by looking ahead for the parenthesis following the function name. This distinction is required otherwise if someone added a user-function one day that happened to be the name of a symbol used in many places, considerably confusion would result.


  Example: pow = pow + 3 
  Result: 3    (pow is a symbol)
  
  Example: pow (4, 3)
  Result: 64   (4 to the power 3)
  
  Example: pow = pow (4, 3), pow = pow + 1
  Result: 65    


In this example we are mixing pow (4, 3) - a function - with pow as a symbol name. Confusing, perhaps, but it works consistently.


  Example: abc (20)
  Result: (exception) Function 'abc' not implemented.




Using in a program

To use the parser in C++ code, use it like this:


  #include "parser.h"
  
  Parser p ("2 + 3 * 6");
  double result = p.Evaluate ();


The expression is not evaluated until the Evaluate function is called. If you need change the expression to be evaluated you can do it by passing a string to Evalute, eg.


  Parser p ();
  double result = p.Evaluate ("2 + 3 * 6");


Variables can be fed in, or retrieved, using operator[], like this:


  Parser p ();
  p ["a"] = 22;  // value for symbol "a"
  p ["b"] = 33;  // value for symbol "b"
  double result = p.Evaluate ("c = a + b");
  double c = p ["c"];   // retrieve symbol "c"


This effectively lets you not only return a result (the evaluated expression) but change other symbols as side-effects.



Using in fight calculations etc. in a MUD

Basically follow the guidelines above for doing calculations.

You could "feed in" the relevant variables from the player's stats (eg. str, dex, wis).

eg.


  Parser p ("str * 3 + dex / 3");

  p ["str"] = player->str;
  p ["dex"] = player->dex;

  double result = p.Evalute ();


Example:

A fighter fixes an arrow to his bow. He takes between 2 and 8 seconds, depending on his strength:


  time_taken =  8 - 6 * (str / max_str)


In this case if his normalised strength is the maximum (1) then the calculation will effectively be:


  8 - (6 * 1) = 2 seconds


However if his strength is zero, the calculation will be:


  8 - (6 * 0) = 8 seconds


To throw in a bit of luck you might roll a dice. For example:


   time_taken =  11 - (6 * (str / max_str)) - roll (1, 3)


This is rolling a 3-sided die once, giving a result in the range 1 to 3.

Thus the worst case would be 10 seconds (11 - 0 - 1) and the best case 2 seconds (11 - 6 - 3).

Maybe 20% of the time he has really bad luck, and takes another 5 seconds:



   time_taken =  11 - (6 * (str / max_str)) - roll (1, 3) + (5 * percent (20))


The "percent (20)" part will return true (that is, 1.0) 20% of the time, which will then be multiplied by 5 to add on another 5 seconds.

To use other variables you might add in dexterity, like this:


  time_taken =  8 - (6 * (str / max_str)) - (dex / max_dex)


Since "dex / max_dex" will be in the range 0 to 1, then this might shave off another second for very dextrous players. For players with 50% dexterity it would shave off half a second.




Downloading

The parser is available for anyone to use, at no charge, It is written in C++ and uses STL (the Standard Template Library).

You can download it from:



File size: 8 Kb (source code only). (Now out-of-date).

The latest version is now available on GitHub:

http://github.com/nickgammon/parser

If you have git installed, you can do this to get a copy:

git clone git://github.com/nickgammon/parser.git





Supported compilers


It has been compiled without errors or warnings under:


  • Cygwin (Windows) - gcc (GCC) 3.3.1 (cygming special)

  • Microsoft Visual Studio 6.0

  • Linux - gcc (GCC) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)

  • Mac OS/X 10.3.5 (Panther) - gcc (GCC) 3.3 20030304 (Apple Computer, Inc. build 1495)


To compile the test program under Cygwin, Linux or Mac OS/X, just run the Makefile (ie. type "make"). To compiler under Visual Studio open the project file parser.dsw.




Using

If you compile as described above you will have a test program (parser, or parser.exe under Windows) which you can run and enter expressions into to test. Note that under Visual C++ it seems to be "a line behind" due to a bug in the standard library. In other words, you need to type 2 expressions before it will evaluate the first. This is only a problem in the test program which you could fix by changing the line:


      getline (cin, inputLine);


To use in your own (C++) programs, simply do this:


#include "parser.h

// and further on

Parser p ("2+2");	// or whatever

double result = p.Evaluate ();


The test program test.cpp can be used as an example of using it in another program.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Mon 13 Sep 2004 10:16 PM (UTC)

Amended on Mon 13 Sep 2004 10:32 PM (UTC) by Nick Gammon

Message
I'll just emphasise that the parser presented above is a completely stand-alone piece of code.

It does not require any additional libraries or files to be installed (such as flex, bison, yacc or whatever).

The exception is that you naturally need the "standard" C++ library, including the Standard Template Library, however that is supplied as standard with the compilers mentioned above, and hopefully with all modern compilers.

To use it, you simply add two files to your project:


  • parser.cpp - the implementation of the expression parser (622 lines). You would add this to your project (makefile).

  • parser.h - the header file, which you would use in any source files that need the parser (133 lines).


- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Reply #2 on Tue 14 Sep 2004 08:41 AM (UTC)
Message
Timing test

It is always important to me that code works quickly. I timed the expression parser described above, to evaluate the expression:


a=10, b=20, a + b


It did this 10,000 times in under a second, on my 2.4 GHz Pentium processor (under Windows NT 4).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Nick Gammon   Australia  (21,322 posts)  [Biography] bio   Forum Administrator
Date Reply #3 on Tue 14 Sep 2004 08:44 AM (UTC)
Message
Comma operator

Some of the examples above use the "comma operator" without really explaining it.

In C, you can separate an expression into parts by using the comma operator. eg.


  a=10, b=20, a + b


This effectively breaks the expression into sub-expressions, as the comma operator has the lowest priority. This means that everything between the commas is done first.

However, as the expression is evaluated left-to-right, what the above example does is:


  • Assign 10 to a

  • Assign 20 to b

  • Add a to b


Thus, the result of that expression is 30.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Peter Claessens   (4 posts)  [Biography] bio
Date Reply #4 on Mon 13 Jun 2005 12:35 PM (UTC)
Message
Hello Nick, forum people,

The Expression parser is a nice piece of code, easy to use, just what I was looking for. I have successfully used it in previous versions of GCC, but unfortunately, the code fails to compile in the DJGPP (i.e., MS-DOS) version of GCC v.3.4.4
The compiler gives me this error message:
"
parser.cpp:229: error: no matches converting function `abs' to type `double (*)(double)'
c:/djgpp/include/stdlib.h:44: error: candidates are: int abs(int)
c:/djgpp/bin/../lib/gcc/djgpp/3.44/../../../../include/cxx/3.44/cstdlib:123: error: long int std::abs(long int)
"
i.e. near this line of code:
#if defined(WIN32)
/* 227 */ STD_FUNCTION (abs<double>);
#else
/* 229 */ STD_FUNCTION (abs);
#endif
I tried forcing the compiler into that first definition of 'abs' by manipulating the preprocessor directives, which gave me this:
"
parser.cpp: In function `int LoadOneArgumentFunctions()':
parser.cpp:227: error: expected primary-expression before "double"
parser.cpp:227: error: expected `;' before "double"
"

I don't know enough about programming in c++ to dare trying to solve this myself (as a matter of fact, I don't know the second error message means).
For now, I simply commented lines 227 and 229. But of course I would prefer the abs function to work. So, is there anyone who knows the solution to this?
Thanks in advance,

Peter.
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #5 on Wed 15 Jun 2005 09:36 AM (UTC)
Message
If I'm not mistaken, the 'correct' form of abs to use is fabs, from math.h. Try including math.h and changing line 229 to "STD_FUNCTION (fabs);".

See:
http://www.delorie.com/djgpp/doc/incs/math.h
for the function prototypes.


Of course, this won't work quite as you'd expect, since it'll register the function fabs, not abs.

What you actually want is something more like this:
//instead of "STD_FUNCTION(fabs);", use this:
OneArgumentFunctions ["abs"] = fabs;


Let me know if this fixes your problem. Don't forget to include math.h in there somewhere.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Peter Claessens   (4 posts)  [Biography] bio
Date Reply #6 on Wed 15 Jun 2005 12:02 PM (UTC)
Message
Dear Ksylian,

Your solution worked, thanks!
Some people might be interested to hear about the following experience under Cygwin. The parser compiles fine, but an abs function is not registered as such. This is the output from a piece of testing code:
"
> evaluate abs(-1)
Could not evaluate expression 'abs(-1)': Function 'abs' not implemented.
"
(note that an exception of type runtime_error has to be caught if you don't want the application to crash with an uninformative "contact the developer" error message)

The cygwin compilation goes into the #ifdef WIN32 block (in LoadOneArgumentFunctions() ) and registers abs<double>, which has the effect that under cygwin, you can call an abs function in the resulting executable, but only as "abs<double>(-1)" (for example). But I suppose the abs function that gets called, is not the one that is meant in the implementation, since it is the version that takes and returns int arguments:

"
> evaluate abs<double>(-1.3)
1
"

I suppose that the line "STD_FUNCTION (abs<double>)" works in Visual C++, but obviously confuses the GCC compiler, which is why I would argue to replace that #ifdef WIN32 to a check of definition that is more specific, i.e. #ifdef _MSC_VER . The correction that you, Ksylian, proposed, works for all GCC compiler versions, DJGPP, Cygwin, and all the others, I assume. Therefore, to summarize, I propose to change the code in lines 221-225

#ifdef WIN32  
  STD_FUNCTION (abs<double>);
#else
  STD_FUNCTION (abs);
#endif  

to

/* #ifdef WIN32 */ #ifdef _MSC_VER
  STD_FUNCTION (abs<double>);
#else
 /* STD_FUNCTION (abs); */ OneArgumentFunctions["abs"]=fabs; 
#endif  

Actually, I suppose that the latter solution should work on all C++ compilers, which would maybe allow to get rid of that conditional compilation alltogether, assuming that there are no speed tradeoffs.

Another note: I used the wrong reference to line numbers in my previous post because I had changed some code in order to be able to compile under GCC 3.4.4 . More specifically, the DoMax and DoMin functions would not compile, apparently due to strict type checking (ambiguous overloading). This is why I propose to replace lines 171-179 in the original file:

const double DoMin (const double arg1, const double arg2)
  {
  return min<double> (arg1, arg2);
  }

const double DoMax (const double arg1, const double arg2)
  {
  return max<double> (arg1, arg2);
  }

to the rather obvious and maybe dumb

const double DoMin (const double arg1, const double arg2)
  {
  /*  return min<double>(arg1, arg2);*/ return (arg1 < arg2 ? arg1 : arg2) ;
  }

const double DoMax (const double arg1, const double arg2)
  {
  /*  return max<double> (arg1, arg2); */ return (arg1 > arg2 ? arg1 : arg2) ;
  }


Of course some people might like a solution in terms of conditional compilation better, but again, I suppose that the above code works on all compilers, assuming no speed issues.

Hope this is useful to someone. Thanks again, Ksylian.

Regards,
Peter.
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #7 on Wed 15 Jun 2005 06:21 PM (UTC)
Message
Glad to be of help. :)
Quote:
Actually, I suppose that the latter solution should work on all C++ compilers, which would maybe allow to get rid of that conditional compilation alltogether, assuming that there are no speed tradeoffs.
I think you're correct. Windows also defines fabs in math.h, so using that would probably removed the need for conditional compilation. The only speed tradeoff is that you are casting everything to doubles even if there's an int version of the function, but since the expression parser works with doubles anyhow, that shouldn't be a problem.
Quote:
(Speaking of DoMin, DoMax) Of course some people might like a solution in terms of conditional compilation better, but again, I suppose that the above code works on all compilers, assuming no speed issues.
I'm a little surprised that code didn't compile; what errors were you getting? But yes, that code should work everywhere, and there's no reason to believe it's less efficient than the provided min<>, max<> routines.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Peter Claessens   (4 posts)  [Biography] bio
Date Reply #8 on Thu 16 Jun 2005 11:55 AM (UTC)
Message
I'm stupid. If I had looked into the exact error messages and the code more carefully, I would have known what was going on with this min/max problem...
This is the error that I get when compiling DoMin (idem for DoMax, of course):
Quote:

/cygdrive/c/src/dots2002/parser.h:7: warning: ignoring #pragma warning
/cygdrive/c/src/dots2002/parser.cpp: In function `const double DoMin(double, dou
ble)':
/cygdrive/c/src/dots2002/parser.cpp:173: error: call of overloaded `min(const double&, const double&)' is ambiguous
/cygdrive/c/src/dots2002/parser.h:12: note: candidates are: T min(T, T) [with T = double]
/usr/lib/gcc/i686-pc-mingw32/3.4.4/include/c++/bits/stl_algobase.h:151: note: const _Tp& std::min(const _Tp&, const _Tp&) [with _Tp = double]

parser.h:7 is (// disable warnings about long names) #pragma warning( disable : 4786) - but I don't think this affects anything.

parser.cpp:173 is :

const double DoMin (const double arg1, const double arg2)
  {
/*173 */   return min<double>(arg1, arg2);
  }

parser.h:12 is around

  // under Visual C++ 6 these do not seem to exist
  template <typename T> 
  inline T min (const T a, const T b)
    {
    return (a < b) ? a : b;
    } // end of min

this is in turn subject to the #ifdef WIN32 compilation condition (see comment in header: "// under Visual C++ 6 these do not seem to exist"). So the point seems to be, again, that cygwin subjects itself to a condition (being win32) which was only meant for visual C++. If I change the line #ifdef WIN32 (line 4 in parser.h) to #ifdef _MSC_VER, everything compiles just fine, with the original DoMin and DoMax code.

Another mystery solved...
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #9 on Thu 16 Jun 2005 08:21 PM (UTC)
Message
Ohhh, that makes a lot of sense. The min was being defined twice!

Changing it to _MSC_VER is a good fix and is probably better in the long run. Ah, who'd'a'thunk that compiling between Windows and Cygwin would make so many problems. It's funny, because I'm fairly sure I compiled stuff under Cygwin using WIN32 ifdefs and they weren't considered true.

Another good fix would be to qualify the use of STL's min with std:: - in other words, change line 173 to:
return std::min<double>(arg1, arg2);
This way, there is no ambiguity as to which min you're calling.

As for min<> not existing in Visual Studio... I don't know about 6, but in .NET 2003 min<> is defined in <algorithm>. I don't remember offhand if Nick included that in his source; perhaps that would fix the need for having to redefine the min<> function.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Raz   (32 posts)  [Biography] bio
Date Reply #10 on Thu 16 Jun 2005 08:23 PM (UTC)
Message
A few comments:

In parser.h:

>#include <math.h>
>#include <time.h>

Uh oh. Why not use the more appropiate C++ files cmath and ctime? You could easily mess up programs that use the C++ header files names with the old C file names.

>using namespace std;

This is fine, but does it really have to be in the header file? You have now intruded on my global namespace, which doesn't make me a happy programmer. Weird effects could easily come from this.

#define MAKE_STRING(msg) \
   (((ostringstream&) (ostringstream() << boolalpha << msg)).str())


That just looks wrong. To me, you are just asking for the temporary to be destroyed before you can get to the data.

const double Evaluate (const string program);  // get result


Why not a reference? std::string is not cheap to copy.

Parser.cpp:

First, I see you using std::rand(), but you don't include cstdlib. Or is std::rand() not in cstdlib?

Down the file, I see dubious floating point comparisons. I suggest reading this: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
This explains a potential problem as well as a good solution.


-Raz
C++ Wiki: http://danday.homelinux.org/dan/cppwiki/index.php
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #11 on Thu 16 Jun 2005 08:33 PM (UTC)
Message
The MAKE_STRING macro works just fine, actually.

Where do you see std::rand()? Nick never uses it explicitly in parser.cpp. Since he doesn't qualify it with std::, it'll pick whatever it finds from the global namespace or from the 'used' std namespace.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Raz   (32 posts)  [Biography] bio
Date Reply #12 on Thu 16 Jun 2005 08:34 PM (UTC)
Message
>So the point seems to be, again, that cygwin subjects itself to a condition (being win32) which was only meant for visual C++.<

Are you sure Cygwin defines WIN32? I tried this program on my Cygwin:


#include <iostream>

int main( void )
{
#ifdef WIN32
   std::cout << "Hello" << std::endl;
#endif
}


I got no output when I ran it under the Cygwin g++ 3.3.3. (Although, I then used the -mno-cygwin option and got the response "Hello" from the program.) I haven't tested this program under a compiler that was compiled under Cygwin yet, though...

-Raz
C++ Wiki: http://danday.homelinux.org/dan/cppwiki/index.php
[Go to top] top

Posted by David Haley   USA  (3,881 posts)  [Biography] bio
Date Reply #13 on Thu 16 Jun 2005 08:43 PM (UTC)
Message
He's actually using DJGPP, I think, which would probably explain why WIN32 is getting defined.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
[Go to top] top

Posted by Raz   (32 posts)  [Biography] bio
Date Reply #14 on Thu 16 Jun 2005 08:58 PM (UTC)
Message
>The MAKE_STRING macro works just fine, actually.

Not on my system:


#include <iostream>
#include <sstream>

#define MAKE_STRING(msg) \
 (((std::ostringstream&)(std::ostringstream()<<msg)).str())

int main( void )
{
   std::cout << MAKE_STRING("Hi") << std::endl;
}


Using Cygwin with a g++ of 3.3.3, I get "0x435000".

I am not 100% sure what it wrong. I am trying to figure it out, but g++ seems to be giving me very different results when I try to create a similar test case.

>Where do you see std::rand()?

He doesn't. I just call rand() by the name of std::rand() when using C++. (It's a matter of habit.)

>Since he doesn't qualify it with std::, it'll pick whatever it finds from the global namespace or from the 'used' std namespace.

Sure. I was just commenting on how he forgot to include the standard header file cstdlib which includes the definition of std::rand().

-Raz
C++ Wiki: http://danday.homelinux.org/dan/cppwiki/index.php
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


75,909 views.

This is page 1, subject is 5 pages long: 1 2  3  4  5  [Next page]

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at FutureQuest]