Subject: RE: [hackers-il] Sash

From: Chen Shapira <[email-masked]>
Date: Tue, 4 Jul 2000 10:43:18 +0200

> I meant, why couldn't you just type "exec bash" rather than a filename
> (don't tell me exec bash is too long to type - I'll tell you that it
> is much easier to remember :)? I thought Chen said there was no
> .sashrc, so we have no place to put exec bash, right? Maybe I
> misunderstand the situation - I don't use sash.

Sash has .aliasrc functioning as a .sashrc (it reads the file and parses it
line by line the same way it parses command line).

Two things Sash doesn't have, and that I want:

1) Command line editing, readline.c style.
2) Scripting language that can be used on command line and files.

They aren't difficult to implement, but I hate bloating a perfect
minimalistic code.

One thing I started thinking about:

Sash implements function such as isNumber() as macros. I usually impelement
those as functions (actually using those in stdlib, but sash couldn't use
those).

If I have a very small function - when should I put it as macro?

Thanks,
Chen.

---

From: Moshe Zadka <[email-masked]>
Date: Tue, 4 Jul 2000 11:29:11 +0300 (IDT)

> If I have a very small function - when should I put it as macro?

Never -- premature optimization, etc. If you do find a ned to optimize,
see if you can limit yourself to gcc and just use __inline__ (or, if you
have a C++ compiler, use inline and compile the C code as C++)

--
Moshe Zadka <[email-masked]>
There is no GOD but Python, and HTTP is its prophet.

---

From: Oleg Goldshmidt <[email-masked]>
Date: 04 Jul 2000 20:44:07 +0300

> have a C++ compiler, use inline and compile the C code as C++)

I usually adopt an even stricter approach. Don't inline anything
unless you are sure that it's a bottleneck. That's the first principle
of optimization -- don't. That's what Moshe said explicitly. Now to
the "etc." part...

Inlining introduces compile-time dependencies where they often are
unneeded or downright dangerous.  At the very least, the last part
refers to non-static (public) inlined functions.

Consider this:

1) The body of the inlined function has to be available (e.g. in an
included header file) to the client (the programmer who uses your
code). This means that if you decide to change the implementation - as
opposed to interface - of the function, the client will have to
recompile his code and everything that depends on it.  Not a problem
for a homework, but in a large production system this matters a
lot. If the function is not inlined, the client will only have to
relink - much less time, much less effort.

2) Switching inlining on and off will also force your client to
recompile.

3) Probably the most troublesome: Any object that is passed to,
returned from, or just used in the body of the function *in size*
(i.e. its definition must be seen at compile time) is never insulated
from the clients. In a lot of cases such object are (or can be)
insulated, greatly reducing the dependency count (and thus the compile
cost) of the client code.

This is true for both C and C++. The same problems exist for macros,
but macros (C macros, of course) are even worse, because they have all
sorts of problems with side effects et caetera. I strongly agree with
Moshe - don't use macros unless you have to. You really need macros in
two cases: for conditional compilation and for abstracting
compile-time constants (array sizes). Don't even use macros to
abstract other types of constants - use enums or something (you'll be
glad when you debug).

I do use macros in another setting. A macro has the following useful
feature: it allows a level of abstraction and can be an lvalue. So I
use macros as *private* (only private!) accessors to my C data
structures. This allows me to modify the structure layout and to
change the macro accessors appropriately, without touching much
implementation code. This is probably not very relevant in C++.

Well, this is all fine as a matter of principle. In practice there
are other possible uses, such as encapsulating common code patterns
(careful!). But there is no reason to use macros for efficiency in
general or for inlining in particular.

Isn't hackers-il the place where we are supposed to share tools
and tricks of the trade? I'd like to see more discussions on general
programming and s/w engineering topics, related or not to particular
OSs, languages, whatever. Something like "when to use macros" or
"when to use inlining" seems to be a good start.

-- 
Oleg Goldshmidt <[email-masked]> 
"... We work but wit, and not by witchcraft;
 And wit depends on dilatory time." [Shakespeare]

---

From: Shlomi Fish <[email-masked]>
Date: Thu, 6 Jul 2000 21:23:18 +0300 (IDT)

> have a C++ compiler, use inline and compile the C code as C++)

Actually, when I programmed Freecell Solver I used macros for all the
board and card access routines. I just did not want to take the risk that
they will run as functions with their extra overhead. I'm doing quite a
lot of board and card lookups and movements there.

Some of my macros would not have been possible as functions because they
receive a struct as a parameter and operate on it. Naturally, passing an
entire struct as a function argument is very impractical, and plus it
cannot be modified. I suppose I would have used a pointer had I written
them as functions.

I think my program would be much slower if they were functions, and I did
not think of gcc's inline at the time. Not to mention that I wanted it to
compile on any C compiler including Microsoft Visual C++.

Just my twenty agoroth.

	Shlomi Fish
 
> ------------------------------------------------------------------------
> Free Conference Calling with Firetalk!
> Click Here!
> http://click.egroups.com/1/5480/12/_/_/_/962699363/
> ------------------------------------------------------------------------
> 
> To unsubscribe from this group, send an email to:
> [email-masked]
> 
> 
> 
> 

----------------------------------------------------------------------
Shlomi Fish        [email-masked] 
Home Page:         http://t2.technion.ac.il/~shlomif/
Home E-mail:       [email-masked]

The prefix "God Said" has the extraordinary logical property of 
converting any statement that follows it into a true one.

---

From: Moshe Zadka <[email-masked]>
Date: Thu, 6 Jul 2000 21:54:52 +0300 (IDT)

> lot of board and card lookups and movements there.

Optimizing before you even profile is very unproductive

> cannot be modified. I suppose I would have used a pointer had I written

And the problem with always passing around pointers to structs is?

> compile on any C compiler including Microsoft Visual C++.

Ummmmm...thinking before you type can be a valuable skill. MSVC++ has
inline by virtue of being a C++ compiler.

---

From: Shlomi Fish <[email-masked]>
Date: Fri, 7 Jul 2000 22:53:32 +0300 (IDT)

> Optimizing before you even profile is very unproductive

I beg your pardon, but I have some a priori knowledge about how my program
is going to run, how many times a function will be called, and thus I
have an idea of what to implement as a macro.

I don't think it is wise to write a program without a good thought about
he it should be optimized a priory. Writing code with poor performance
just to get a program which you can run, wastes more time in comparison
to thinking about the implementation and then writing a high-performance
code.

Don't get me wrong: I did have to optimize the code between Freecell
Solver 0.2 and Freecell Sovler 0.4, and as a result it now runs dozens of
time faster. But I still think my decision to use macros instead of
functions was in its place.

> And the problem with always passing around pointers to structs is?

There's no problem with that, only that a macro is still faster. Of course
a smart compiler that can handle inline functions _might_ optimize
functions which receives pointers to structures to the same speed of their
corresponding macros. But I didn't want to take that chance.

> inline by virtue of being a C++ compiler.

Yes, but I wanted this code to be ANSI C, not C++. I'm not sure if MSVC
has inline support in ANSI C modules. And even if it has there are other
compilers (like all those crammy UNIX cc's) which don't. And I wanted to
stick to the stanard and not depend on a compiler specific feature.

If anynone would like to download the Freecell Solver source and see all
the macros which I had to write (actually I wrote two versions of each
macro), he can download it from my homepage:

http://vipe.technion.ac.il/~shlomif/freecell-solver/

FYI, Freecell Solver is freely distributable under the public domain.

> Remember four years of good friends, bad clothes, explosive chemistry 
> experiments.
> http://click.egroups.com/1/5532/12/_/_/_/962909705/

---

From: Oleg Goldshmidt <[email-masked]>
Date: 08 Jul 2000 19:10:30 +0300

Shlomi Fish <[email-masked]> writes:

> they will run as functions with their extra overhead. 

I don't think there is extra overhead to an inlined function call as
compared to a macro. They are basically the same. Of course, inlining
is no more than a hint to the compiler, not a directive, so you cannot
be 100% sure that your function will be inlined. On the other hand,
it might be a good idea to trust the compiler that it has a good
reason not to inline.

If you are sure that none of the bad properties of C macros are
important, and the design arguments I listed are not important,
then there is no problem with macros. From your description, it looks
like you use them in your own code only, and not in an interface, so
the issues I listed are not relevant to you.

> cannot be modified. I suppose I would have used a pointer had I written

Precisely.

> compile on any C compiler including Microsoft Visual C++.

C++ compilers all have inline. If it is C code, then portability is an
issue indeed.

Overall, if I understand your situation correctly, you have a good
case, but caution is always in order.