Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Assorted questions from a C++ programmer (http://www.velocityreviews.com/forums/t437975-assorted-questions-from-a-c-programmer.html)

V.Ch. 05-10-2005 08:01 PM

Assorted questions from a C++ programmer
 
In near future I can face a prospect of writing some stuff in C. Being a
C++ programmer, I've got practically no experience in C. I'd be obliged
if someone could answer the following questions (from specific to more
general):

1. Having looked though some C sources I was horrified by the number of
macros. E.g., what could be the purpose of using this:

#define CFG_REF(c, f) ((c) -> f)
#define SERVER_ADDRESS(c) CFG_REF (c, server_address)


From the point of view of C++ coding, this would seem quite idiotic
(why not use -> operator directly?!). But I've got reasons to believe
that the guy who wrote this is a good C coder.

2. If you were to write some program that can potentially be compiled on
a number of platforms by different compilers, how would you declare
automatic variables? Does it pay of to be extra conservative and don't
assume that every compiler now supports C99 with respect to declaring
variables wherever you want? Personally, I find it not only tiresome,
but actually very bad to declare all the variables at the beginning of a
block. But then again, I am not a C programmer. Is there any consensus
here?

3. What are the ways to structure large programs? I am falling back to
C++ again, thinking about object-oriented programming in C (something
like fopen, fread/fwrite and fclose) and emulating VTBL interfaces with
vectors of function pointers. Any other aproaches here? Any
links/tutorials would be very welcome.

4. Any other links and suggestions that would be useful for a C++
programmer that has to write in C.

Walter Roberson 05-10-2005 08:26 PM

Re: Assorted questions from a C++ programmer
 
In article <d5r3ug$1v6t$1@gavrilo.mtu.ru>, V.Ch. <fake@notreal.com> wrote:
>I'd be obliged
>if someone could answer the following questions (from specific to more
>general):


>1. Having looked though some C sources I was horrified by the number of
>macros. E.g., what could be the purpose of using this:


>#define CFG_REF(c, f) ((c) -> f)
>#define SERVER_ADDRESS(c) CFG_REF (c, server_address)


Hiding of implementation. The data structure could be completely
replaced, possibly by functions, with very little change to the code.


>2. If you were to write some program that can potentially be compiled on
>a number of platforms by different compilers, how would you declare
>automatic variables? Does it pay of to be extra conservative and don't
>assume that every compiler now supports C99 with respect to declaring
>variables wherever you want?


Yes, it does pay. Actual C99 implementations are rare -- at least
ones that support the full library. Without the full library, it is
in effect "C89 plus extensions and some bugs", and as soon as you
start down the "extensions" path you are sure to lose portability.


>3. What are the ways to structure large programs?


Many different ways, depending on what you are trying to achieve
and what the natural problem decomposition is.

I've even heard of people who believe that every source file should
have at most one function... but that requires exposing private data
structures.

>I am falling back to
>C++ again, thinking about object-oriented programming in C (something
>like fopen, fread/fwrite and fclose) and emulating VTBL interfaces with
>vectors of function pointers. Any other aproaches here? Any
>links/tutorials would be very welcome.


What domain of problem are you trying to deal with? Unless you
have the same kind of operations being performed on a number of
ideologically similar but not identicially-structured objects, the VTBL
approach is probably a waste.

Above, was the reference to fopen etc. along the lines that you were
planning to do the equivilent of smalltalk's [self print]
in which arbitrary objects might get juggled around but you need to
be able to tell them to pretty-print themselves? Or are you working
with something like a graphics package where you want to be able
manipulate a number of different kinds of objects, and you want it
to be extensible without changing the draw code, just by implementing
new objects? [If so, then one approach that can work is to
have each object type call "registration" routines, with
the function pointers kept track of (one per -type- per functionality).
The routine that needs to invoke variable behaviour then searches
its registry table by type number and calls the associated function
pointer on the object.
--
'The short version of what Walter said is "You have asked a question
which has no useful answer, please reconsider the nature of the
problem you wish to solve".' -- Tony Mantler

V.Ch. 05-10-2005 09:02 PM

Re: Assorted questions from a C++ programmer
 
Walter Roberson wrote:
> Yes, it does pay. Actual C99 implementations are rare -- at least
> ones that support the full library.


I am not interested much in anything else than variable declaration
part. Are you saying that I cannot rely even on that?

> What domain of problem are you trying to deal with?


Well, for now I am not going to touch anything big - just an Apache
module. I don't think it will need any king of structure :). The
question about structuring a big program was less practical (at least
for now), I asked it mainly out of quriosity.

> Above, was the reference to fopen etc. along the lines that you were
> planning to do the equivilent of smalltalk's [self print]
> in which arbitrary objects might get juggled around but you need to
> be able to tell them to pretty-print themselves?


Don't know anything about smalltalk. What I meant was quite simple
actually, that instead of a C++ class I would create a C module in which I:

1. Declare a struct to hold state variables of an "object" (FILE)
2. "Constructor" - function that creates an object and returns a
"handle" (fopen).
3. "Methods" - functions that take this "handle" as a parameter
(fread/fwrite).
4. "Destructor" (fclose)

Eric Sosman 05-10-2005 09:18 PM

Re: Assorted questions from a C++ programmer
 


V.Ch. wrote:
> In near future I can face a prospect of writing some stuff in C. Being a
> C++ programmer, I've got practically no experience in C. I'd be obliged
> if someone could answer the following questions (from specific to more
> general):


First, read Walter Roberson's response; I'm just tossing
in a few minor additions.

> 2. If you were to write some program that can potentially be compiled on
> a number of platforms by different compilers, how would you declare
> automatic variables? Does it pay of to be extra conservative and don't
> assume that every compiler now supports C99 with respect to declaring
> variables wherever you want? Personally, I find it not only tiresome,
> but actually very bad to declare all the variables at the beginning of a
> block. But then again, I am not a C programmer. Is there any consensus
> here?


In C90 a block's variable declarations must precede all
its executable statements. However, blocks can nest to give
you a partial simulation of what you're looking for:

int func(int arg) {
int a; /* "function global" */
...
{
double x; /* "block local" */
...
}
...
{
char x[100]; /* nothing to do with prior `x' */
...
}
...
return 42;
}

You can even recycle a "current" identifier in a nested block,
but I'd avoid it -- can you spell "maintenance nightmare?"

Whether it's burdensome to park the variable declarations
at the start of a function depends on how many variables there
are. If you've got a Whole Lot of local variables and they
don't belong to a few tightly-related groups, it may be time
to think about splitting up the function. Small functions
improve manageability, and at the same time they tend to keep
the population of local variables under control.

> 3. What are the ways to structure large programs? I am falling back to
> C++ again, thinking about object-oriented programming in C (something
> like fopen, fread/fwrite and fclose) and emulating VTBL interfaces with
> vectors of function pointers. Any other aproaches here? Any
> links/tutorials would be very welcome.


If you want to write C++ programs, write them in C++ and
don't try to "port your language" to C. A programmer who
insists on writing "C-ish" code for a C++ environment is
usually making a mistake; the reverse is equally mistaken.
Seek C-ish solutions; don't try to bend C into a poor man's
version of C++. You'll wind up with something that's neither
fish nor fowl, a feathered fish that neither swims nor flies.

"A Real Programmer can write FORTRAN in any language."

--
Eric.Sosman@sun.com


Keith Thompson 05-10-2005 09:30 PM

Re: Assorted questions from a C++ programmer
 
"V.Ch." <fake@notreal.com> writes:
> Walter Roberson wrote:
>> Yes, it does pay. Actual C99 implementations are rare -- at least
>> ones that support the full library.

>
> I am not interested much in anything else than variable declaration
> part. Are you saying that I cannot rely even on that?


Right, you can't rely on being able to mix declarations and statements
if you want your C to be completely portable. It's likely to work on
a number of systems, but you could later need to port the code to a
system that doesn't have a C compiler that supports this C99 feature.

You can, of course, reduce the scope of a variable by creating a
block:

void foo(void)
{
int x;
statement;
statement;
{
int y;
statement;
statement;
}
}

If this causes the nesting level to become uncomfortably deep, you can
either declare everything at the top of the function or consider that
your function might be too big.

On the other hand, if you're not concerned about absolute portability,
you might be able to get away with mixing declarations and statements.
For example, if you can count on every system your code might run on
to have a sufficiently recent version of gcc, you can use gcc
extensions. (Note that gcc extensions, other than the ones that are
part of C99, are off-topic here.)

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.

Walter Roberson 05-10-2005 09:53 PM

Re: Assorted questions from a C++ programmer
 
In article <d5r7ft$21et$1@gavrilo.mtu.ru>, V.Ch. <fake@notreal.com> wrote:
>I am not interested much in anything else than variable declaration
>part. Are you saying that I cannot rely even on that?


For clarity: are you refering to the ability to declare variables
where convenient, or are you refering to variable-length arrays?

There are still quite a number of compilers that are C89 without
any ability to declare variables in convenient places. Variable-length
arrays are less common.

You could restrict yourself to gcc4, which I believe supports both
features. Generally speaking, you really have to be disciplined when
you program in gcc, as they tend to throw in extensions without
making it clear that they are extensions.

Historically, gcc has had issues with silently accepting non-portable
code even when warnings were turned on: their excuse has been along the
lines of, "The ANSI standards only bind compilers that claim compliance
with the standard. Since we don't claim compliance with the standard,
we are free to ignore any part of the standard we want, and free to
implement extensions without warning that they are extensions."

>> What domain of problem are you trying to deal with?


>What I meant was quite simple
>actually, that instead of a C++ class I would create a C module in which I:


>1. Declare a struct to hold state variables of an "object" (FILE)
>2. "Constructor" - function that creates an object and returns a
>"handle" (fopen).
>3. "Methods" - functions that take this "handle" as a parameter
>(fread/fwrite).
>4. "Destructor" (fclose)


Apache (the original) at least [don't know about Apache2] wasn't
written in that kind of style, so it might be a bit much to expect
other people to adopt that style to use your module.

IMHO, there isn't a lot of point in adopting a class-like structure
for those functions, not unless you plan to write a -number- of different
apache modules and want them all to have the same interface.
Just do what everyone else does and use routine names that are
module specific. The users will call the routine with the right name
and you won't have to keep function pointers around.

Sometimes it is useful to have a data structure with important state
information: I'm not discouraging that, I'm just indicating that
-likely- in the context you describe, there would not be much point
in storing function pointers, as they would probably always be the -same-
function pointer.
--
This signature intentionally left... Oh, darn!

CBFalconer 05-11-2005 12:23 AM

Re: Assorted questions from a C++ programmer
 
"V.Ch." wrote:
>
> In near future I can face a prospect of writing some stuff in C.
> Being a C++ programmer, I've got practically no experience in C.
> I'd be obliged if someone could answer the following questions
> (from specific to more general):
>

.... snip ...
>
> 3. What are the ways to structure large programs? I am falling
> back to C++ again, thinking about object-oriented programming
> in C (something like fopen, fread/fwrite and fclose) and
> emulating VTBL interfaces with vectors of function pointers.
> Any other aproaches here? Any links/tutorials would be very
> welcome.


I suggest you take a look at the structure and interface of my
hashlib package, for what I (for some reason) consider good C
code. You probably need read no more than the .h and .c files.
They are to be found in:

<http://cbfalconer.home.att.net/download/hashlib.zip>

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson



Malcolm 05-11-2005 11:18 PM

Re: Assorted questions from a C++ programmer
 

"Eric Sosman" <eric.sosman@sun.com> wrote
> A programmer who
> insists on writing "C-ish" code for a C++ environment is
> usually making a mistake; the reverse is equally mistaken.
>

You certainly often see C++ programs which are horrible kludges, and would
have been much better in C.

However I would disagree on "C++ish" C.
In C it is often a good idea to have objects, with contructors and matching
destructors. So if I want a logical regression tree, I declare a structure,
then I declare a function called "logictree()" which creates one, and a
function called "killlogictree()" which destroys it when I am finished. Then
I have a function called ltree_predict() which takes a tree and some
observations as parameters, and predicts the class.

What C is not good at is allowing objects to enter into relationships with
each other. If I decide I want a general class of "logic trees", and a
"nand-only" tree as a special case and a "balanced logic tree" as another
special case, I cannot easily represent that program design using C, and I
am better off with another language.



Eric Sosman 05-12-2005 02:43 AM

Re: Assorted questions from a C++ programmer
 
Malcolm wrote:

> "Eric Sosman" <eric.sosman@sun.com> wrote
>
>>A programmer who
>>insists on writing "C-ish" code for a C++ environment is
>>usually making a mistake; the reverse is equally mistaken.
>>

>
> You certainly often see C++ programs which are horrible kludges, and would
> have been much better in C.
>
> However I would disagree on "C++ish" C.
> In C it is often a good idea to have objects, with contructors and matching
> destructors. [...]


Object-oriented design is a fine thing (in some problem
areas, anyhow), and I have no quarrel with it -- use it m'self
on occasion, ayeh, that I dew.

But the O.P. was talking about "emulating VTBL interfaces
with vectors of function pointers." This is an attempt to graft
the implementation techniques of one language into the body of
another, whose immune systems are likely to kick up all kinds of
ruckus. If he wants VTBL-ish implementation artifacts, I still
maintain he's better off seeking them in C++ than trying to emulate
them in C. One might as well translate C to Lisp by writing a
defun() for malloc() ... Again I repeat the Immortal Words:

"A Real Programmer can write FORTRAN in any language."

Don't spread jam with a meat cleaver; don't quarter a
chicken with a butterknife. Both tasks are possible; neither
would be pleasant.

--
Eric Sosman
esosman@acm-dot-org.invalid




All times are GMT. The time now is 03:11 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.