POV-Ray : Newsgroups : povray.off-topic : My first C++ program Server Time
12 Oct 2026 19:02:44 EDT (-0400)
  My first C++ program (Message 1 to 50 of 149)  
Goto Latest 50 Messages Next 50 Messages >>>
From: Invisible
Subject: My first C++ program
Date: 19 Sep 2008 08:03:59
Message: <48d3952f$1@news.povray.org>
(Yeah, I realise nobody else is going to care...)



#include <iostream>
#include <vector>
#include <string>

using namespace std;

bool StackCheck(vector<int> stack, int min)
{
   if (stack.size() >= min) return true;

   cout << "Stack underflow." << endl;
   return false;
}

void Add(vector<int>& stack)
{
   if (!StackCheck(stack, 2)) return;

   int x = stack.back(); stack.pop_back();
   int y = stack.back(); stack.pop_back();
   stack.push_back(x + y);
}

void Sub(vector<int>& stack)
{
   if (!StackCheck(stack, 2)) return;

   int x = stack.back(); stack.pop_back();
   int y = stack.back(); stack.pop_back();
   stack.push_back(x - y);
}

int main()
{
   cout << "Calc #01" << endl;

   vector<int> stack;
   string cmd;

   while (true)
   {
     for (int i=0; i<stack.size(); i++)
     cout << "[" << i << "]: " << stack[i] << endl;

     cout << "Calc> ";
     cin  >> cmd;

     if (cmd == "^") break;
     if (cmd == "+") {Add(stack); continue;}
     if (cmd == "-") {Sub(stack); continue;}
     stack.push_back(1);
   }

   cout << "Exit." << endl;
}



Almost unbelievably, even though this program is written in C++ and 
involves I/O, it seems to work correctly. I'm sure anybody who actually 
knows how C++ is supposed to work will have a good laugh at this, but I 
learned a few things by doing it.

The first mistake was passing the stack by value - which, obviously, 
fails miserably. The next thing I tried was returning the new stack to 
the caller, but that didn't work either. (Much like C, C++ compiler 
errors seem rather cryptic. Plus I'm running GCC under QEMU, so it takes 
about 60 seconds for each compiler run!)

At present, I haven't figured out how to convert a string to an integer 
yet, so this "calculator" is pretty much useless. I'm sure it'll be 
explained later in the tutorial. I also find myself constantly cursing 
that I have to write an entire 5 lines of (nearly identical) code for 
every arithmetic operation I want to implement and there's no way to 
abstract this. (I don't have copy & paste available!)

Also, there's an interesting glitch where the program won't continue if 
you enter a blank line - you must enter *something* or the program won't 
continue. Presumably this is just the defined behaviour of the >> 
operator...

Still, I have a program that reads user input without segfaulting. 
That's gotta be pretty impressive!

PS. Nano is a horrid, horrid text editor!


Post a reply to this message

From: Invisible
Subject: (And in Haskell. Obviously.)
Date: 19 Sep 2008 08:20:08
Message: <48d398f8$1@news.povray.org>
Invisible wrote:

> #include <iostream>
> #include <vector>
> #include <string>
> 
> using namespace std;
> 
> bool StackCheck(vector<int> stack, int min)
> {
>   if (stack.size() >= min) return true;
> 
>   cout << "Stack underflow." << endl;
>   return false;
> }
> 
> void Add(vector<int>& stack)
> {
>   if (!StackCheck(stack, 2)) return;
> 
>   int x = stack.back(); stack.pop_back();
>   int y = stack.back(); stack.pop_back();
>   stack.push_back(x + y);
> }
> 
> void Sub(vector<int>& stack)
> {
>   if (!StackCheck(stack, 2)) return;
> 
>   int x = stack.back(); stack.pop_back();
>   int y = stack.back(); stack.pop_back();
>   stack.push_back(x - y);
> }
> 
> int main()
> {
>   cout << "Calc #01" << endl;
> 
>   vector<int> stack;
>   string cmd;
> 
>   while (true)
>   {
>     for (int i=0; i<stack.size(); i++)
>     cout << "[" << i << "]: " << stack[i] << endl;
> 
>     cout << "Calc> ";
>     cin  >> cmd;
> 
>     if (cmd == "^") break;
>     if (cmd == "+") {Add(stack); continue;}
>     if (cmd == "-") {Sub(stack); continue;}
>     stack.push_back(1);
>   }
> 
>   cout << "Exit." << endl;
> }

module Main (main) where

main = do
   putStrLn "Calc #01"
   main_loop []

main_loop stack = do
   mapM_ (\(n,v) -> putStrLn $ "[" ++ show n ++ "]: " ++ show v) (zip 
[0..] stack)

   putStr "Calc> "
   cmd <- getLine

   case cmd of
     "^" -> return ()
     "+" -> binary (+) stack
     "-" -> binary (-) stack
     _   -> main_loop (1:stack)

binary fn stack = case stack of
   x:y:zs -> do main_loop ((fn x y) : zs)
   _      -> do putStrLn "Stack underflow."; main_loop stack


Somehow... it seems so much easier in Haskell. ;-)


Post a reply to this message

From: scott
Subject: Re: My first C++ program
Date: 19 Sep 2008 08:23:31
Message: <48d399c3@news.povray.org>
> I also find myself constantly cursing that I have to write an entire 5 
> lines of (nearly identical) code for every arithmetic operation I want to 
> implement and there's no way to abstract this. (I don't have copy & paste 
> available!)

What you could do, is have a function like DoOperation(stack,op), and use 
"op" as a token for the operation.

So you would call it like:

     if (cmd == "+") {DoOP(stack,0); continue;}
     if (cmd == "-") {DoOP(stack,1); continue;}
     if (cmd == "/") {DoOP(stack,2); continue;}
     if (cmd == "*") {DoOP(stack,3); continue;}

Or you could even use some fancy look-up table to convert from the character 
code to op number, or just use the ASCII code of the operator as the op 
number... you get the idea.

Then, DoOperation() would look like:

   if (!StackCheck(stack, 2)) return;

   int x = stack.back(); stack.pop_back();
   int y = stack.back(); stack.pop_back();
   int answer;
   if(op==0) answer=x+y;
   if(op==1) answer=x-y;
   if(op==2) answer=x/y;
   if(op==3) answer=x*y;
   stack.push_back(answer);

I'm sure there's a better way of doing it, but I think that's less work than 
your first version.

PS good work on the first C++ program, it's way cooler than any of my first 
programs.


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 08:27:49
Message: <48d39ac5$1@news.povray.org>
scott wrote:

> What you could do, is have a function like DoOperation(stack,op), and 
> use "op" as a token for the operation.

In other words, move the operation check to the place where all the 
values are available. I guess that could work.

> PS good work on the first C++ program, it's way cooler than any of my 
> first programs.

I figured copying out HelloWorld.cpp didn't count is "MY first program". ;-)

Warp gave me the link of Tuesday, and I have now written working code of 
my own design, not based on any example code. This would have been quite 
impossible in C. (Unless you avoid I/O, anyway.) So it seems they did 
make C++ at least a little easier. ;-)


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 19 Sep 2008 08:59:40
Message: <48d3a23c@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> using namespace std;

  Don't do that. It might feel tempting, but don't. It's better in the long
run to avoid it.

> bool StackCheck(vector<int> stack, int min)

  You are passing the vector by value here, which may not be a good idea,
especially if the vector is big. That's because the entire vector will be
copied. (Some STL implementations *might* use copy-on-write, but most of
them don't, and instead just deep-copy.)

  Teach yourself to intuitively write:

bool StackCheck(const std::vector<int>& stack, int min)

  Usually with big objects (such as vectors) you basically always want
to pass by const reference rather than by value. (You should pass by
value only if that's *really* what you want to do.)

  Sure, this might sound like a nuisance, but C and C++ are value based
languages, and by default everything is passed by value. To pass by
reference (or by pointer) you need additional syntax.

>    int x = stack.back(); stack.pop_back();
>    int y = stack.back(); stack.pop_back();
>    stack.push_back(x + y);

  You could also save a bit of writing by doing it like this:

    int x = stack.back(); stack.pop_back();
    stack.back() += x;

  Or if you want to really minimize things:

    stack.at(stack.size()-2) += stack.back();
    stack.pop_back();

  Of course it starts being a bit obfuscated.

> int main()
> {
>    cout << "Calc #01" << endl;
...
>    cout << "Exit." << endl;
> }

  While it is perfectly valid to omit the return value of main()
(IIRC it defaults to EXIT_SUCCESS), it's generally recommended to
return EXIT_SUCCESS or EXIT_FAILURE (which are defined in some header
file).

  Having said that, when I write very small test programs like this one,
I don't bother writing any return command in main() either. So it's not
that bad. :P

> At present, I haven't figured out how to convert a string to an integer 
> yet, so this "calculator" is pretty much useless.

  It depends on what your input syntax is. Making a parser in C++ is not
one of the easiest things. Especially a stack calculator is difficult
because you can't know what the type of the next input element will be
in advance, but you have to simply read it as a string and then examine
its contents. The next element might be a number or an operator, and you
can't know which until you read it as a string and examine it.

  If the input had a very specific format, then it would be easier.
For example if your input consisted of lines like:

command 1 2

that is, if the keyword "command" appears in the input, it will always
be followed by two integers, then you could write code like this:

std::string keyword;
std::cin >> keyword;
if(keyword == "command")
{
    int x, y;
    std::cin >> x >> y;
    executeCommand(x, y);
}

  But as I said, if the next parameter can be a number or an operator or
a keyword or something else, it becomes more complicated.

> Also, there's an interesting glitch where the program won't continue if 
> you enter a blank line - you must enter *something* or the program won't 
> continue. Presumably this is just the defined behaviour of the >> 
> operator...

  If you call >> with a string, then it will read the input until it finds
a whitespace-delimited string. >> is not line-based in any way, it's
whitespace-based.

> PS. Nano is a horrid, horrid text editor!

  Why don't you use something better?

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 09:11:17
Message: <48d3a4f5$1@news.povray.org>
>> using namespace std;
> 
>   Don't do that.

So noted.

>> bool StackCheck(vector<int> stack, int min)
> 
>   You are passing the vector by value here, which may not be a good idea,
> especially if the vector is big. That's because the entire vector will be
> copied.

Right, OK.

> bool StackCheck(const std::vector<int>& stack, int min)
> 
>   Usually with big objects (such as vectors) you basically always want
> to pass by const reference rather than by value.

Ooo... I didn't realise you could do that. (Pass a const reference, that 
is.) So that means, what? If you accidentally try to change it, you'll 
get a compiler warning? Can you do that with non-reference types? (Not 
that it would matter if you were to change those - except that your 
program might not do what you intended.)

>>    int x = stack.back(); stack.pop_back();
>>    int y = stack.back(); stack.pop_back();
>>    stack.push_back(x + y);
> 
>   You could also save a bit of writing by doing it like this:
> 
>     int x = stack.back(); stack.pop_back();
>     stack.back() += x;
> 
>   Or if you want to really minimize things:
> 
>     stack.at(stack.size()-2) += stack.back();
>     stack.pop_back();
> 
>   Of course it starts being a bit obfuscated.

...ouch.

>   While it is perfectly valid to omit the return value of main()
> (IIRC it defaults to EXIT_SUCCESS), it's generally recommended to
> return EXIT_SUCCESS or EXIT_FAILURE (which are defined in some header
> file).

Noted.

Since you're here... do you happen to know the C++ name for stderr?

>> At present, I haven't figured out how to convert a string to an integer 
>> yet, so this "calculator" is pretty much useless.
> 
>   It depends on what your input syntax is. Making a parser in C++ is not
> one of the easiest things. Especially a stack calculator is difficult
> because you can't know what the type of the next input element will be
> in advance, but you have to simply read it as a string and then examine
> its contents. The next element might be a number or an operator, and you
> can't know which until you read it as a string and examine it.

I was thinking along the lines of "each line of input is either +, -, or 
a number". But I don't know how to convert a string into a number. 
Apparently the ">>" operator will do this if you hand it a number-type 
variable, so there must be some library function somewhere that does the 
conversion. I just don't know it's name yet.

>> Also, there's an interesting glitch where the program won't continue if 
>> you enter a blank line - you must enter *something* or the program won't 
>> continue. Presumably this is just the defined behaviour of the >> 
>> operator...
> 
>   If you call >> with a string, then it will read the input until it finds
> a whitespace-delimited string. >> is not line-based in any way, it's
> whitespace-based.

Well, that's consistent at least.

>> PS. Nano is a horrid, horrid text editor!
> 
>   Why don't you use something better?

Because my virtual machine is slow enough already without starting X11, 
and Nano is the only text-mode editor I have available (other than Vim 
and Emacs anyway).


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 09:35:35
Message: <48d3aaa7$1@news.povray.org>
>> I also find myself constantly cursing that I have to write an entire 5 
>> lines of (nearly identical) code for every arithmetic operation I want 
>> to implement and there's no way to abstract this. (I don't have copy & 
>> paste available!)
> 
> What you could do, is have a function like DoOperation(stack,op), and 
> use "op" as a token for the operation.

I wrote a function that returns the top element from the stack while 
simultaneously removing it. That cuts down the typing quite a bit.

Note to self: Do *not* attempt to remove an element from an empty vector...


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 10:05:39
Message: <48d3b1b3$1@news.povray.org>
Invisible wrote:

> At present, I haven't figured out how to convert a string to an integer 
> yet, so this "calculator" is pretty much useless. I'm sure it'll be 
> explained later in the tutorial.

The tutorial recommends the C function atoi() - which, being a C 
function, is about as user-friendly as Windows 2. Much hair-pulling 
involving pointers ensues.

(It turns out that you can assign a string to a char*, but not the 
reverse. Go figure. Anyway, the solution is simple enough...)


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 10:10:25
Message: <48d3b2d1$1@news.povray.org>
void *(*(*fp1)(int))[10];

...OK, I'm scared! o_O

At least when somebody writes (Either (Maybe (Set Int) (Map Int String)) 
[(Word32, Int -> IO Int)]), it's relatively easy to work out what that is.

(Presumably in either language, if you ever write something like this 
for real, you're doing something worribly wrong somewhere...)


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 19 Sep 2008 10:56:08
Message: <48d3bd88@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> > bool StackCheck(const std::vector<int>& stack, int min)
> > 
> >   Usually with big objects (such as vectors) you basically always want
> > to pass by const reference rather than by value.

> Ooo... I didn't realise you could do that. (Pass a const reference, that 
> is.) So that means, what? If you accidentally try to change it, you'll 
> get a compiler warning?

  No, you get a compiler error. Since you declared the parameter as const,
you *can't* modify it.

  Declaring everything you don't intend to modify as 'const' is a good
programming practice in C++ for many reasons:

1) If you don't intend to modify the parameter, very especially if the
   parameter is a reference (in which case you would be modifying the
   original rather than a copy), then you will get a compiler error if
   you try to modify it anyways. This will catch programming mistakes
   at compile time, which is a good thing.

2) Declaring a reference parameter as 'const' is self-documenting: You are
   not only telling the compiler that that parameter is not modified in the
   function, more importantly you are telling that to a human reader. In
   other words, you are effectively documenting that the parameter is a
   pure input parameter, not something the function uses to pass values
   to the calling code.

3) As a bonus, it is possible that in certain situations the compiler might
   be able to optimize const variables better than non-const ones.

  Personally I have got the habit of declaring *everything* that I don't
intend to modify as 'const'. Even simple local variables. For example
I will typically write code like this:

    const int retVal = someFunction();
    somethingElse();
    return ratVal;

  In principle there's no need for the 'const' there, but I have got the
habit of doing it. After a while it becomes self-documenting even for
myself.

> Can you do that with non-reference types?

  Yes. Anything can be declared 'const', even variables and parameters
which are passed by value. In other words, it's perfectly possible to
do this:

void foo(const int value)
{
    const int anotherValue = value+1;
    ...
}

  In practice you seldom see 'const' used in function parameters like
that, though.

  Note that (not surprisingly) pointers are slightly more complicated
with regard to 'const':

    const Type* ptr = something;

  This defines a pointer named 'ptr' which points to a const value.
In other words, you can't modify the value pointed by 'ptr'. However,
you can modify 'ptr' itself, to make it point somewhere else (or make
it null, of whatever).

  If what you want is for 'ptr' itself to be const, not the value it's
pointing to, you have to write it like this:

    Type* const ptr = something;

  Now you can modify the value pointed by 'ptr' but you can't modify 'ptr'
itself. Naturally if you want *both* things, you write:

    const Type* const ptr = something;

  Now you can't modify either 'ptr' nor the value it's pointing to.

  References do not have this kind of complication because the reference
variable itself is always const. What the 'const' keyword determines is
whether the object it's pointing to is const or not.

> Since you're here... do you happen to know the C++ name for stderr?

  std::cerr << "An error message.\n";

  (Anything taking an std::ostream& can be given std::cout or std::cerr
as parameter. Or an output file stream. Or an output string stream.)

> I was thinking along the lines of "each line of input is either +, -, or 
> a number". But I don't know how to convert a string into a number. 
> Apparently the ">>" operator will do this if you hand it a number-type 
> variable, so there must be some library function somewhere that does the 
> conversion. I just don't know it's name yet.

  The problem with the >> operator is that you have to know in advance
what the type of the input will be. In this case you don't know it because,
as you say, the input can be an operator (+ or -) or a number.

  What you can do is this:

    std::string s;
    while(true)
    {
        std::cin >> s;
        if(!std::cin.good()) break;

        int value;
        std::istringstream iss(s);
        iss >> value;
        if(!iss.fail())
            std::cout << "The input was an integer: " << value << "\n";
        else
            std::cout << "The input was something else: " << s << "\n";
    }

> >> PS. Nano is a horrid, horrid text editor!
> > 
> >   Why don't you use something better?

> Because my virtual machine is slow enough already without starting X11, 
> and Nano is the only text-mode editor I have available (other than Vim 
> and Emacs anyway).

  Why don't you use an editor in your host OS?

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 19 Sep 2008 10:56:56
Message: <48d3bdb8@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> The tutorial recommends the C function atoi() - which, being a C 
> function, is about as user-friendly as Windows 2. Much hair-pulling 
> involving pointers ensues.

  No need for atoi(). You can use stringstreams, as I wrote in the other
post.

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 11:09:56
Message: <48d3c0c4@news.povray.org>
Warp wrote:

>   No need for atoi(). You can use stringstreams, as I wrote in the other
> post.

I did think using a C function seemed a little bogus.

(For one thing, AFAIK, there is *no way* to know whether atoi() 
succeeded or failed; if it "fails", you get a zero. So was the string 
actually a zero, or did the conversion fail??)


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 11:10:50
Message: <48d3c0fa$1@news.povray.org>
>> Ooo... I didn't realise you could do that. (Pass a const reference, that 
>> is.) So that means, what? If you accidentally try to change it, you'll 
>> get a compiler warning?
> 
>   No, you get a compiler error.

Even better.

>   Declaring everything you don't intend to modify as 'const' is a good
> programming practice in C++ for many reasons:
> 
> 1) If you don't intend to modify the parameter, very especially if the
>    parameter is a reference (in which case you would be modifying the
>    original rather than a copy), then you will get a compiler error if
>    you try to modify it anyways. This will catch programming mistakes
>    at compile time, which is a good thing.
> 
> 2) Declaring a reference parameter as 'const' is self-documenting: You are
>    not only telling the compiler that that parameter is not modified in the
>    function, more importantly you are telling that to a human reader. In
>    other words, you are effectively documenting that the parameter is a
>    pure input parameter, not something the function uses to pass values
>    to the calling code.
> 
> 3) As a bonus, it is possible that in certain situations the compiler might
>    be able to optimize const variables better than non-const ones.

Agreed.

>   Note that (not surprisingly) pointers are slightly more complicated
> with regard to 'const':
> 
>     const Type* ptr = something;
> 
>   This defines a pointer named 'ptr' which points to a const value.
> In other words, you can't modify the value pointed by 'ptr'. However,
> you can modify 'ptr' itself, to make it point somewhere else (or make
> it null, of whatever).
> 
>   If what you want is for 'ptr' itself to be const, not the value it's
> pointing to, you have to write it like this:
> 
>     Type* const ptr = something;
> 
>   Now you can modify the value pointed by 'ptr' but you can't modify 'ptr'
> itself. Naturally if you want *both* things, you write:
> 
>     const Type* const ptr = something;
> 
>   Now you can't modify either 'ptr' nor the value it's pointing to.
> 
>   References do not have this kind of complication because the reference
> variable itself is always const. What the 'const' keyword determines is
> whether the object it's pointing to is const or not.

...ouch. >_< OK, well let's hope I don't need to use pointers too much then!

>> Since you're here... do you happen to know the C++ name for stderr?
> 
>   std::cerr << "An error message.\n";

OK.

>   The problem with the >> operator is that you have to know in advance
> what the type of the input will be. In this case you don't know it because,
> as you say, the input can be an operator (+ or -) or a number.

Indeed.

>   What you can do is this:
> 
>     std::string s;
>     while(true)
>     {
>         std::cin >> s;
>         if(!std::cin.good()) break;
> 
>         int value;
>         std::istringstream iss(s);
>         iss >> value;
>         if(!iss.fail())
>             std::cout << "The input was an integer: " << value << "\n";
>         else
>             std::cout << "The input was something else: " << s << "\n";
>     }

...you mean, you can take a string and make a stream that will read from 
it? (Or, presumably, write to it, if you desire.) So what exactly do the 
good() and fail() functions do?

>>>> PS. Nano is a horrid, horrid text editor!
>>>   Why don't you use something better?
> 
>> Because my virtual machine is slow enough already without starting X11, 
>> and Nano is the only text-mode editor I have available (other than Vim 
>> and Emacs anyway).
> 
>   Why don't you use an editor in your host OS?

Because I haven't found a way to transfer files between the host OS and 
the guest OS.


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 19 Sep 2008 11:31:55
Message: <48d3c5ea@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> ...you mean, you can take a string and make a stream that will read from 
> it? (Or, presumably, write to it, if you desire.)

  Correct. Or, more precisely, you can write to an ostringstream and then
get a regular string out of it (with the str() function).

  Where this becomes fancy is when a function takes an std::istream or an
std::ostream reference, for example:

void readSomethingFrom(std::istream& is) { ... }
void writeSomethingTo(std::ostream& os) { ... }

  You can give those functions any of these things:

readSomethingFrom(std::cin);

std::ifstream inputFile("filename.txt");
readSomethingFrom(inputFile);

std::istringstream iss(someString);
readSomethingFrom(iss);

writeSomethingTo(std::cout);
writeSomethingto(std::cerr);

std::ofstream outputFile("filename.txt");
writeSomethingTo(outputFile);

std::ostringstream oss;
writeSomethingTo(oss);

  The functions themselves don't know (and don't need to know) what the
exact type of stream actually is. All of them are used in the same way.
For example:

void writeSomethingTo(std::ostream& os)
{
    for(int i = 0; i < 10; ++i)
        os << i << "\n";
}

  This is, in fact, pure object-oriented programming (all of those things
are inherited from std::istream or std::ostream, so they can be given to
those two functions). Beautiful.

> So what exactly do the good() and fail() functions do?

http://www.cplusplus.com/reference/iostream/ios/good.html
http://www.cplusplus.com/reference/iostream/ios/fail.html

  Basically you can think of good() as "did the last read succeed?"
(the most common reason for the stream to be not good() is EOF).
It's an overall "is the stream still good?".

  And fail() as "did the input contain a value of the correct type?".
In other words, with the "std::cin >> integer; if(std::cin.fail() ..."
you are asking "did reading an integer fail?". The most common reason
for fail() to be true is that input did not contain what was expected
by the parameter (in this example an integer value).

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 19 Sep 2008 11:35:36
Message: <48d3c6c7@news.povray.org>
Invisible <voi### [at] devnull> wrote:
> Warp wrote:

> >   No need for atoi(). You can use stringstreams, as I wrote in the other
> > post.

> I did think using a C function seemed a little bogus.

  There's merit in those C functions, though: They are much more efficient
than using stringstreams. (For one, they parse the string *in place*,
rather than copying the string around in memory.)

  Of course their usage is more difficult.

> (For one thing, AFAIK, there is *no way* to know whether atoi() 
> succeeded or failed; if it "fails", you get a zero. So was the string 
> actually a zero, or did the conversion fail??)

  Another C function can be used to both parse an integer from a string
and know if there was one: strtod(). However, its usage is even more
complicated than atoi().

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: My first C++ program
Date: 19 Sep 2008 11:37:52
Message: <48d3c750$1@news.povray.org>
>> ...you mean, you can take a string and make a stream that will read from 
>> it? (Or, presumably, write to it, if you desire.)
> 
>   Correct. Or, more precisely, you can write to an ostringstream and then
> get a regular string out of it (with the str() function).

Ah  - because a string is fixed-size once created?

>   Where this becomes fancy is when a function takes an std::istream or an
> std::ostream reference.
>   The functions themselves don't know (and don't need to know) what the
> exact type of stream actually is. All of them are used in the same way.
>   This is, in fact, pure object-oriented programming (all of those things
> are inherited from std::istream or std::ostream, so they can be given to
> those two functions). Beautiful.

OOP as it should be.

>> So what exactly do the good() and fail() functions do?
> 
> http://www.cplusplus.com/reference/iostream/ios/good.html
> http://www.cplusplus.com/reference/iostream/ios/fail.html
> 
>   Basically you can think of good() as "did the last read succeed?"
> (the most common reason for the stream to be not good() is EOF).
> It's an overall "is the stream still good?".
> 
>   And fail() as "did the input contain a value of the correct type?".
> In other words, with the "std::cin >> integer; if(std::cin.fail() ..."
> you are asking "did reading an integer fail?". The most common reason
> for fail() to be true is that input did not contain what was expected
> by the parameter (in this example an integer value).

OK... So good() is a property of the stream, and fail() is a property of 
the last thing read from it?


Post a reply to this message

From: Mueen Nawaz
Subject: Re: My first C++ program
Date: 19 Sep 2008 11:38:05
Message: <48d3c75d@news.povray.org>
Invisible wrote:

> Also, there's an interesting glitch where the program won't continue if 
> you enter a blank line - you must enter *something* or the program won't 
> continue. Presumably this is just the defined behaviour of the >> 
> operator...

	If you DO want to read a whole line, look up the getline function. That 
will also take in an "empty" line.

-- 
Inoculatte: To take coffee intravenously when you are running late.


                     /\  /\               /\  /
                    /  \/  \ u e e n     /  \/  a w a z
                        >>>>>>mue### [at] nawazorg<<<<<<
                                    anl


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 19 Sep 2008 15:31:33
Message: <48d3fe15$1@news.povray.org>
Warp wrote:

>   What you can do is this:
> 
>     std::string s;
>     while(true)
>     {
>         std::cin >> s;
>         if(!std::cin.good()) break;
> 
>         int value;
>         std::istringstream iss(s);
>         iss >> value;
>         if(!iss.fail())
>             std::cout << "The input was an integer: " << value << "\n";
>         else
>             std::cout << "The input was something else: " << s << "\n";
>     }

"Variable 'iss' has initialiser but has incomplete type."

WTF...?

Oh, wait, I see. That means "you didn't include <sstream>". Well, that 
was quite clear. o_O

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 19 Sep 2008 15:39:24
Message: <48d3ffec$1@news.povray.org>
Spot the mistake:

int foo(vector<int>& stack)
{
   int x = stack.back();
   stack.pop_back();
}

For reasons I can't begin to understand,

1. This doesn't produce any compile-time error.

2. This function always returns the value "2144912088".

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Darren New
Subject: Re: My first C++ program
Date: 19 Sep 2008 16:02:04
Message: <48d4053c$1@news.povray.org>
Invisible wrote:
>>> PS. Nano is a horrid, horrid text editor!
>>
>>   Why don't you use something better?
> 
> Because my virtual machine is slow enough already without starting X11, 
> and Nano is the only text-mode editor I have available (other than Vim 
> and Emacs anyway).

Well, that made *me* laugh.

"Nano is awful. I have nothing better. Oh, except the two most popular 
text editors."

-- 
Darren New / San Diego, CA, USA (PST)


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 19 Sep 2008 16:05:00
Message: <48d405ec$1@news.povray.org>
Darren New wrote:

> Well, that made *me* laugh.
> 
> "Nano is awful. I have nothing better. Oh, except the two most popular 
> text editors."

Have *you* ever tried to make Vim or Emacs work? :-P

Besides, Emacs isn't even a text editor - it's an operating system! ;-)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Mueen Nawaz
Subject: Re: My first C++ program
Date: 19 Sep 2008 16:15:49
Message: <48d40875$1@news.povray.org>
Orchid XP v8 wrote:
> Spot the mistake:
> 
> int foo(vector<int>& stack)
> {
>   int x = stack.back();
>   stack.pop_back();
> }
> 
> For reasons I can't begin to understand,
> 
> 1. This doesn't produce any compile-time error.
> 
> 2. This function always returns the value "2144912088".

	Function lacks a return statement.

-- 
Inoculatte: To take coffee intravenously when you are running late.


                     /\  /\               /\  /
                    /  \/  \ u e e n     /  \/  a w a z
                        >>>>>>mue### [at] nawazorg<<<<<<
                                    anl


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 19 Sep 2008 16:19:31
Message: <48d40953$1@news.povray.org>
Mueen Nawaz wrote:
> Orchid XP v8 wrote:
>> Spot the mistake:
> 
>     Function lacks a return statement.

Yup. A simple and obvious mistake. But unfortunately, not one the 
compiler warned me about. (I'm also curios to know exactly what the hell 
the function is returning... No doubt the reason there's no compiler 
warning is that this is actually a valid thing to do due to some bizare 
C language rule kept for compatibility or something random like that.)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Vincent Le Chevalier
Subject: Re: My first C++ program
Date: 19 Sep 2008 16:31:10
Message: <48d40c0e@news.povray.org>
Orchid XP v8 a écrit :
> Mueen Nawaz wrote:
>> Orchid XP v8 wrote:
>>> Spot the mistake:
>>
>>     Function lacks a return statement.
> 
> Yup. A simple and obvious mistake. But unfortunately, not one the 
> compiler warned me about. (I'm also curios to know exactly what the hell 
> the function is returning... No doubt the reason there's no compiler 
> warning is that this is actually a valid thing to do due to some bizare 
> C language rule kept for compatibility or something random like that.)
> 
If you are using g++, you can add the option -Wall to your command line. 
The compiler should give a warning in this case... Well two actually, 
one because the variable x is not used for anything and one because the 
function does not return.

I'm leaving the explanation of why this is still legal to someone more 
competent :-)

-- 
Vincent


Post a reply to this message

From: Darren New
Subject: Re: My first C++ program
Date: 19 Sep 2008 17:51:59
Message: <48d41eff$1@news.povray.org>
Orchid XP v8 wrote:
> Have *you* ever tried to make Vim or Emacs work? :-P

I have used both for years at a time. I prefer vim, except for one 
stretch of time when it was still "vi" and I wanted automatic 
indentations for Tcl.

-- 
Darren New / San Diego, CA, USA (PST)


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: (And in Haskell. Obviously.)
Date: 19 Sep 2008 18:56:12
Message: <48d42e0c@news.povray.org>
Invisible wrote:
> Somehow... it seems so much easier in Haskell. ;-)

I understand the C++ one and the Haskell one looks like line noise.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: My first C++ program
Date: 19 Sep 2008 19:02:40
Message: <48d42f90@news.povray.org>
Invisible wrote:
>>> ...you mean, you can take a string and make a stream that will read from
>>> it? (Or, presumably, write to it, if you desire.)
>> 
>>   Correct. Or, more precisely, you can write to an ostringstream and then
>> get a regular string out of it (with the str() function).
> 
> Ah  - because a string is fixed-size once created?

No. std::string is mutable, and can change its size.

This is how you can convert numbers to/from strings:

int answer = 42;
std::ostringstream oss;
oss << answer;

//oss.str() returns a std::string containing "42".

-------------

int answer;
std::istringstream iss("42");
iss >> answer;

//answer now contains the number 42.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: My first C++ program
Date: 19 Sep 2008 19:03:22
Message: <48d42fb9@news.povray.org>
Orchid XP v8 wrote:
> Darren New wrote:
> 
>> Well, that made *me* laugh.
>> 
>> "Nano is awful. I have nothing better. Oh, except the two most popular
>> text editors."
> 
> Have *you* ever tried to make Vim or Emacs work? :-P 

Vim is my main text editor. Even on Windows.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: My first C++ program
Date: 19 Sep 2008 19:07:41
Message: <48d430bc@news.povray.org>
Invisible wrote:
> Warp wrote:
> 
>>   No need for atoi(). You can use stringstreams, as I wrote in the other
>> post.
> 
> I did think using a C function seemed a little bogus.
> 
> (For one thing, AFAIK, there is *no way* to know whether atoi()
> succeeded or failed; if it "fails", you get a zero. So was the string
> actually a zero, or did the conversion fail??)

atoi is always a bad idea.

If you're writing C, you should use strtol instead. If you're writing C++,
you should use a stringstream instead.

Or use boost lexical_cast, which looks like a cast but works with streams to
do string-number conversions. But any boost library involves lots of
inter-library dependencies, and would surely increase your compilation
times (the compiler has to untangle all the templated mess :P). So just
stick to streams.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: My first C++ program
Date: 19 Sep 2008 19:09:09
Message: <48d43115@news.povray.org>
Orchid XP v8 wrote:
> (I'm also curios to know exactly what the hell
> the function is returning...

Whatever random value happened to be in the appropriate place of the stack.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: My first C++ program
Date: 19 Sep 2008 19:33:45
Message: <48d436d8@news.povray.org>
Invisible wrote:
> I wrote a function that returns the top element from the stack while
> simultaneously removing it. That cuts down the typing quite a bit.

The reason that isn't built-in is that it doesn't work well with objects.

If vector.pop_back() returned a reference to the popped object, you'd get
sure crashes (reading from freed memory, or at least, a destructed object).

If vector.pop_back() returned a copy of the popped object, you'd get bad
performance even when you don't need the object (useless copying), you just
want to remove it. And who would free that copy?

ints, however, are easily copyable and don't need "freeing" :)


Post a reply to this message

From: Slime
Subject: Re: My first C++ program
Date: 20 Sep 2008 00:59:53
Message: <48d48349$1@news.povray.org>
> int foo(vector<int>& stack)
> {
>   int x = stack.back();
>   stack.pop_back();
> }
>
> For reasons I can't begin to understand,
>
> 1. This doesn't produce any compile-time error.

What compiler are you using?

If it's possible for you to acquire a copy of Visual Studio (even an oldish 
one), I strongly recommend it.

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

From: Slime
Subject: Re: My first C++ program
Date: 20 Sep 2008 01:07:51
Message: <48d48527$1@news.povray.org>
> The tutorial recommends the C function atoi() - which, being a C function, 
> is about as user-friendly as Windows 2. Much hair-pulling involving 
> pointers ensues.
>
> (It turns out that you can assign a string to a char*, but not the 
> reverse. Go figure. Anyway, the solution is simple enough...)

C strings aren't so bad. If you have a std::string, you can call its c_str() 
method to get a (const) pointer to the internal string, which is just a 
sequence of bytes. So, you can use

atoi( mystring.c_str() )

to convert to an integer. This is what I always use, though I see there are 
other ways to do it.

> (For one thing, AFAIK, there is *no way* to know whether atoi()
succeeded or failed; if it "fails", you get a zero. So was the string
actually a zero, or did the conversion fail??)

As I understand it, atoi's behavior is to return the integer represented by 
the longest sequence of characters starting at the beginning of the string 
that represent an integer, defaulting to 0. By this definition it's not 
possible to fail. =) Sometimes this is useful.

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

From: Slime
Subject: Re: My first C++ program
Date: 20 Sep 2008 01:13:53
Message: <48d48691$1@news.povray.org>
> What you could do, is have a function like DoOperation(stack,op), and use 
> "op" as a token for the operation.

>     if (cmd == "+") {DoOP(stack,0); continue;}
>     if (cmd == "-") {DoOP(stack,1); continue;}
>     if (cmd == "/") {DoOP(stack,2); continue;}
>     if (cmd == "*") {DoOP(stack,3); continue;}

This is good, but instead of using integers like 0 1 2 3, I'd use an enum:

enum Operation
{
    OP_ADD,
    OP_SUBTRACT,
    OP_DIVIDE,
    OP_MULTIPLY,
};

An enum gives meaning to this sort of approach so you don't have to remember 
what something like "2" means.

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

From: Manuel Kasten
Subject: Re: My first C++ program
Date: 20 Sep 2008 03:09:15
Message: <48d4a19b@news.povray.org>
Slime schrieb:
> What compiler are you using?
> 
> If it's possible for you to acquire a copy of Visual Studio (even an oldish 
> one), I strongly recommend it.
> 

Related to that, the express editions of Visual Studio are available 
free of charge. Some say that the express editions are somewhat limited, 
I however did not run into any walls with them. OpenGL, DirectX, GUI 
work with Qt, all not a problem. Commandline apps work well, too.

For C/C++ work obviously you only need "Visual C++ 2008 Express 
Edition". Download here: http://www.microsoft.com/express/download/

Manuel Kasten


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 04:45:04
Message: <48d4b810@news.povray.org>
Nicolas Alvarez <nic### [at] gmailcom> wrote:
> If you're writing C, you should use strtol instead. If you're writing C++,
> you should use a stringstream instead.

  As I said in my other post, there is merit in the C functions: They are
much more efficient than stringstreams.

  So if you are converting a *huge* amount of strings to ints in a tight
loop, you might want to consider the C functions rather than stringstreams.

  In situations where speed has absolutely no relevance stringstreams are
much easier and safer to use.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 04:47:04
Message: <48d4b888@news.povray.org>
Warp <war### [at] tagpovrayorg> wrote:
>   Another C function can be used to both parse an integer from a string
> and know if there was one: strtod(). However, its usage is even more
> complicated than atoi().

  Yeah, it's strtol(), not strtod(). The latter is to read a floating
point number.

  (This shows how clear those C function names are... ;) )

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 04:49:55
Message: <48d4b932@news.povray.org>
Slime <fak### [at] emailaddress> wrote:
> atoi( mystring.c_str() )

> to convert to an integer. This is what I always use, though I see there are 
> other ways to do it.

  The problem is that with atoi() you can't know if there was an integer
in that string in the first place. If there wasn't, it just returns zero,
and you can't know if there was a zero in the string or something which
was not a parseable number.

  (And no, it's not enough to check if mystring[0] == '0'. There are a
multitude of other ways for a valid number 0 to be in the string.)

  This might be very relevant if you are checking if there was a number
of something else in the string, and act accordingly.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 04:59:13
Message: <48d4bb61@news.povray.org>
Mueen Nawaz <m.n### [at] ieeeorg> wrote:
>         If you DO want to read a whole line, look up the getline function. That 
> will also take in an "empty" line.

  The problem with getline() is precisely that it reads an entire line.
If there are several whitespace-separated things in that line, it will
still read the entire line.

  Of course you can give that line to istringstream and then read those
whitespace-separated things with >> (and check with good() to see if it
succeeds).

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 05:20:05
Message: <48d4c045@news.povray.org>
Orchid XP v8 <voi### [at] devnull> wrote:
> Yup. A simple and obvious mistake. But unfortunately, not one the 
> compiler warned me about.

  Than turn on the warning flags. You should always compile with warning
flags.

g++ -Wall -Wextra -pedantic -ansi -O3 yourprogram.cc

  Learn to use makefiles too. You can use the attached generic makefile
to automatically build your program. (You'll probably need gnu make.)

  (Note that if you add, remove or change any #include line in your
program, except those which include standard libraries, you'll have to
delete the .dep file before running make.)


Post a reply to this message


Attachments:
Download 'Makefile.txt' (1 KB)

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 05:58:53
Message: <48d4c95d@news.povray.org>
>> Yup. A simple and obvious mistake. But unfortunately, not one the 
>> compiler warned me about.
> 
>   Than turn on the warning flags. You should always compile with warning
> flags.
> 
> g++ -Wall -Wextra -pedantic -ansi -O3 yourprogram.cc

Actually, when I want to compile something, I usually just say "make 
foo". Otherwise GCC insists on naming it "a.out", which is very irritating.

I'm rather surprised that forgetting to return anything at all isn't 
considered a non-maskable error, but anyway... (Certainly returning 
something from a void function seems to cause an error.)

I guess at some point I'll have to read the GCC manpage to find out how 
to control it directly.

>   Learn to use makefiles too. You can use the attached generic makefile
> to automatically build your program. (You'll probably need gnu make.)
> 
>   (Note that if you add, remove or change any #include line in your
> program, except those which include standard libraries, you'll have to
> delete the .dep file before running make.)

So there *is* a way to automate dependency analysis?

Personally, I'm used to a programming language where I write some code, 
save it in a couple of files, and say "ghc --make Foo" and it 
automatically builds a dependency tree, decides which things do or don't 
need recompiling (including noting whether the *external* interface is 
different or not), compiles everything to machine code, and 
automatically links all the necessary libraries.

This whole concept of having to manually write makefiles and manually 
write header files and so forth just seems tedious and error-prone.

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 05:59:43
Message: <48d4c98f$1@news.povray.org>
Slime wrote:

> What compiler are you using?

GCC, on Linux, running under QEMU. (Because it's what I have to hand.)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:00:36
Message: <48d4c9c4$1@news.povray.org>
>> If it's possible for you to acquire a copy of Visual Studio (even an 
>> oldish one), I strongly recommend it.
>>
> 
> Related to that, the express editions of Visual Studio are available 
> free of charge.

Hmm. OK, maybe I'll give that a try at some point.

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:02:18
Message: <48d4ca2a$1@news.povray.org>
Warp wrote:
> Warp <war### [at] tagpovrayorg> wrote:
>>   Another C function can be used to both parse an integer from a string
>> and know if there was one: strtod(). However, its usage is even more
>> complicated than atoi().
> 
>   Yeah, it's strtol(), not strtod(). The latter is to read a floating
> point number.
> 
>   (This shows how clear those C function names are... ;) )

<insert "I told you so" remarks here> ;-)

At least C++ manages to be a little more intuitive here.

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:05:23
Message: <48d4cae3$1@news.povray.org>
Orchid XP v8 wrote:

> Besides, Emacs isn't even a text editor - it's an operating system! ;-)

More technically, "Emacs isn't a text editor, it's an EList interpretter 
that comes bundled with a text editor implementation". :^)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:06:07
Message: <48d4cb0f$1@news.povray.org>
>> Have *you* ever tried to make Vim or Emacs work? :-P
> 
> I have used both for years at a time.

Well forget the comments about M$ Word training courses - surely you 
must have taken some pretty advanced courses to be able to comprehend 
either of these editors!

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:07:30
Message: <48d4cb62@news.povray.org>
Orchid XP v8 <voi### [at] devnull> wrote:
> Orchid XP v8 wrote:

> > Besides, Emacs isn't even a text editor - it's an operating system! ;-)

> More technically, "Emacs isn't a text editor, it's an EList interpretter 
> that comes bundled with a text editor implementation". :^)

  I use emacs to write C++, in both Linux and Windows (where I program
for my payjob). Of course it's a heavily configured emacs.

  If you ever want to use emacs, I could give you my emacs configuration
file. It sets up quite many things which make it more usable.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:22:34
Message: <48d4cee9@news.povray.org>
Orchid XP v8 <voi### [at] devnull> wrote:
> > g++ -Wall -Wextra -pedantic -ansi -O3 yourprogram.cc

> Actually, when I want to compile something, I usually just say "make 
> foo". Otherwise GCC insists on naming it "a.out", which is very irritating.

  If you don't specify an executable name, how can gcc guess what is it
that you want? Note that you can write something like:

g++ file1.cc file2.cc file3.cc

  Which one of those is the one you want the executable named after?
Or maybe you don't want the executable to be named anything those.

  AFAIK all compilers require you to specify an executable name. It's
just that in most compilers this happens when you are creating a project.
However, gcc is command-line oriented and doesn't have projects. It doesn't
need to support projects because 'make' is the de-facto project software
in unix systems, and there's no need for gcc to step onto its toes.

  Of course the way to tell gcc the name of the executable is to tell it
to it with the -o parameter.

> I'm rather surprised that forgetting to return anything at all isn't 
> considered a non-maskable error, but anyway...

  C++ inherits many things from C, good and bad.

> >   Learn to use makefiles too. You can use the attached generic makefile
> > to automatically build your program. (You'll probably need gnu make.)
> > 
> >   (Note that if you add, remove or change any #include line in your
> > program, except those which include standard libraries, you'll have to
> > delete the .dep file before running make.)

> So there *is* a way to automate dependency analysis?

  The -MM option of gcc (which I use in that generic makefile I attached)
auto-generates makefile dependencies for all the specified source
files. Makefiles themselves (at least with gnu make) are so versatile
that this can be used to completely automatize dependency building.

  Well, *almost* completely. 'make' has no way of knowing if you have
changed some #include line in some source code file, which would change
the dependencies. Of course it would be perfectly possible to make it
build the dependency file every time you run 'make', but I usually don't
want that, because the "g++ -MM" command often takes a few seconds to run,
which can be irritating, and dependencies change rarely.

  If you want it to run the "g++ -MM" every time, you can do it like in
the attached Makefile.

> This whole concept of having to manually write makefiles and manually 
> write header files and so forth just seems tedious and error-prone.

  You don't need to manually write makefiles. Just use a generic one.


Post a reply to this message


Attachments:
Download 'Makefile.txt' (1 KB)

From: Orchid XP v8
Subject: Re: (And in Haskell. Obviously.)
Date: 20 Sep 2008 06:25:05
Message: <48d4cf81$1@news.povray.org>
Nicolas Alvarez wrote:

> I understand the C++ one and the Haskell one looks like line noise.

Uh-huh, and let me guess: You already know how to read and write C++ 
fluently, but you know nothing about Haskell yet? :-P

Seriously, I am constantly baffled by statements like this. The code I 
posted contains one line which is a little cryptic (the really long one 
where I dump the stack to stdout with 1 line of code). Other than that, 
it's all really quite straightfoward.

Or are you seriously telling me that the meaning of

     if (cmd == "^") break;
     if (cmd == "+") {Add(stack); continue;}
     if (cmd == "-") {Sub(stack); continue;}
     stack.push_back(1);

is somehow clearer than

   case cmd of
     "^" -> return ()
     "+" -> binary (+) stack
     "-" -> binary (-) stack
     _   -> main_loop (1:stack)

?

To me, all that tricky slight of hand with "break" and "continue" seems 
far less clear then just directly saying exactly what you want to 
happen, as the Haskell version does.

I really can't figure out what everybody finds so confusing about 
Haskell. Is it just that it uses different syntax to other "common" 
programming languages? (E.g., no curly braces, no function call 
brackets.) Or is it something deeper?

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Orchid XP v8
Subject: Re: My first C++ program
Date: 20 Sep 2008 06:32:41
Message: <48d4d149$1@news.povray.org>
>> Actually, when I want to compile something, I usually just say "make 
>> foo". Otherwise GCC insists on naming it "a.out", which is very irritating.
> 
>   If you don't specify an executable name, how can gcc guess what is it
> that you want? Note that you can write something like:
> 
> g++ file1.cc file2.cc file3.cc

Now there's interesting. I didn't know you could actually compile 
multiple source files together; I was under the impression that in that 
case, you must manually invoke g++ several times, and then manually 
invoke ld to produce the final binary. (Or, more likely, write a 
makefile that does that.)

>   C++ inherits many things from C, good and bad.

Apparently so. ;-)

[I'm currently compiling a list...]

>> So there *is* a way to automate dependency analysis?
> 
>   The -MM option of gcc (which I use in that generic makefile I attached)
> auto-generates makefile dependencies for all the specified source
> files. Makefiles themselves (at least with gnu make) are so versatile
> that this can be used to completely automatize dependency building.

Well, that's a step up from manually writing a makefile, writing it 
wrong, and producing a binary that segfaults because it's built from 
incompatible object files...

>> This whole concept of having to manually write makefiles and manually 
>> write header files and so forth just seems tedious and error-prone.
> 
>   You don't need to manually write makefiles. Just use a generic one.

Has anybody come up with a tool for autogenerating header files yet?

(Presumably you'd need to edit such a file to remove references to 
things that aren't meant to be public, but at least the function names 
and signatures would match.)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

Goto Latest 50 Messages Next 50 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.