3

everyone. I actually have two questions, somewhat related.

Question #1: Why is gcc letting me declare variables after action statements? I thought the C89 standard did not allow this. (GCC Version: 4.4.3) It even happens when I explicitly use --std=c89 on the compile line. I know that most compilers implement things that are non-standard, i.e. C compilers allowing // comments, when the standard does not specify that. I'd like to learn just the standard, so that if I ever need to use just the standard, I don't snag on things like this.

Question #2: How do you cope without objects in C? I program as a hobby, and I have not yet used a language that does not have Objects (a.k.a. OO concepts?) -- I already know some C++, and I'd like to learn how to use C on it's own. Supposedly, one way is to make a POD struct and make functions similar to StructName_constructor(), StructName_doSomething(), etc. and pass the struct instance to each function - is this the 'proper' way, or am I totally off?

EDIT: Due to some minor confusion, I am defining what my second question is more clearly: I am not asking How do I use Objects in C? I am asking How do you manage without objects in C?, a.k.a. how do you accomplish things without objects, where you'd normally use objects?

In advance, thanks a lot. I've never used a language without OOP! :)

EDIT: As per request, here is an example of the variable declaration issue:

/* includes, or whatever */
int main(int argc, char *argv[]) {
    int  myInt = 5;
    printf("myInt is %d\n", myInt);
    int test = 4; /* This does not result in a compile error */
    printf("Test is %d\n", test);
    return 0;
}
FurryHead
  • 1,479
  • 3
  • 16
  • 19
  • 1. Can you provide an example the declaration issue? 2. C can easily be used for object-oriented programming. Just use structs. – Rafe Kettler May 11 '11 at 15:01
  • 1
    @Rafe - I don't agree. You cannot have member functions in C structs (instead, some function pointers are used to emulate polymorphism and things like this). – Kiril Kirov May 11 '11 at 15:02
  • @Kiril yes you can, using function pointers. But even then, how's that different from passing the struct around to functions? – Rafe Kettler May 11 '11 at 15:03
  • @FurryHead - how exactly you compile the source? Please paste the command. – Kiril Kirov May 11 '11 at 15:04
  • @Rafe Kettler: I updated my OP, with example code. @Kiril Kirov, using the example code in my OP, I compile as: `gcc -Wall test.c -o testvar`, and run ./testvar – FurryHead May 11 '11 at 15:06
  • 7
    You need the `-pedantic` switch to trigger this behavior. The `--std=` switches are used to *add* features rather than remove them. – Tamás Szelei May 11 '11 at 15:07
  • Ok, now I am getting a _warning_ as follows: `test.c: In function 'main': test.c:6: warning: ISO C90 forbids mixed declarations and code` -- shouldn't the standard produce an _error_ ? or am I wrong? – FurryHead May 11 '11 at 15:08
  • @Rafe - I know you can, it's in my comment. But it's not "easily" and you cannot make any constructor (unless using function and passing the "object" as parameter). It's still pretty different. – Kiril Kirov May 11 '11 at 15:08
  • @pmg: Yeah, but it still _compiles_, heh. Good enough, though, I suppose. Thanks a ton! – FurryHead May 11 '11 at 15:20
  • 1
    `-pedantic-errors` will make non-conforming code throw an error. It is useful when portability between compilers is important. – Tamás Szelei May 11 '11 at 15:32
  • It's really bad form to combine two unrelated questions into one... – wnoise May 26 '11 at 20:59

4 Answers4

3
  1. c89 doesn't allow this, but c99 does. Although it's taken a long time to catch on, some compilers (including gcc) are finally starting to implement c99 features.
  2. IMO, if you want to use OOP, you should probably stick to C++ or try out Objective C. Trying to reinvent OOP built on top of C again just doesn't make much sense.

If you insist on doing it anyway, yes, you can pass a pointer to a struct as an imitation of this -- but it's still not a good idea.

It does often make sense to pass (pointers to) structs around when you need to operate on a data structure. I would not, however, advise working very hard at grouping functions together and having them all take a pointer to a struct as their first parameter, just because that's how other languages happen to implement things.

If you happen to have a number of functions that all operate on/with a particular struct, and it really makes sense for them to all receive a pointer to that struct as their first parameter, that's great -- but don't feel obliged to force it just because C++ happens to do things that way.

Edit: As far as how you manage without objects: well, at least when I'm writing C, I tend to operate on individual characters more often. For what it's worth, in C++ I typically end up with a few relatively long lines of code; in C, I tend toward a lot of short lines instead.

There is more separation between the code and data, but to some extent they're still coupled anyway -- a binary tree (for example) still needs code to insert nodes, delete nodes, walk the tree, etc. Likewise, the code for those operations needs to know about the layout of the structure, and the names given to the pointers and such.

Personally, I tend more toward using a common naming convention in my C code, so (for a few examples) the pointers to subtrees in a binary tree are always just named left and right. If I use a linked list (rare) the pointer to the next node is always named next (and if it's doubly-linked, the other is prev). This helps a lot with being able to write code without having to spend a lot of time looking up a structure definition to figure out what name I used for something this time.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • I don't mean that I wnat to use Objects in C - I was trying to ask _how do you *manage* without objects in c_ - sorry if I did not make that clear :( – FurryHead May 11 '11 at 15:09
  • `...to figure out what name I used for something _this_ time` - gotta love that. Anyway, thanks for the tips! :) – FurryHead May 11 '11 at 15:34
1

@Question #1: I don't know why there is no error, but you are right, variables have to be declared at the beginning of a block. Good thing is you can declare blocks anywhere you like :). E.g:

{
    int some_local_var;
}

@Question #2: actually programming C without inheritance is sometimes quite annoying. but there are possibilities to have OOP to some degree. For example, look at the GTK source code and you will find some examples. You are right, functions like the ones you have shown are common, but the constructor is commonly devided into an allocation function and an initialization function. E.G:

someStruct* someStruct_alloc() { return (someStruct*)malloc(sizeof(someStruct)); }
void someStruct_init(someStruct* this, int arg1, arg2) {...}

In some libraries, I have even seen some sort of polymorphism, where function pointers are stored within the struct (which have to be set in the initializing function, of course). This results in a C++ like API:

someStruct* str = someStruct_alloc();
someStruct_init(str);
str->someFunc(10, 20, 30);
Constantinius
  • 34,183
  • 8
  • 77
  • 85
  • Very interesting read. I had not intended to ask, 'How do I use objects in c', but rather 'how do I cope without objects in c' - Though, what you provided was useful. Thanks! – FurryHead May 11 '11 at 15:14
  • 1
    @FurryHead: sorry that I reinterpreted your question. I thought the usual answer: "C++ simply requires another approach than C99" is not the answer you liked to hear. So to correctly answer the question: you use structs and pointers to them a lot. Since there is no polymorphism, you have to explicitly add conditionals in your code and call different functions according to the condition. Personally: I did miss C++ a lot, but I was able to accomplish even larger parts of code, and I realized, C++ is not necessary to implement running code :) – Constantinius May 11 '11 at 15:21
1

Regarding OOP in C, have you looked at some of the topics on SO? For instance, Can you write object oriented code in C?.

I can't put my finger on an example, but I think they enforce an OO like discipline in Linux kernel programming as well.

Community
  • 1
  • 1
Don Wakefield
  • 8,693
  • 3
  • 36
  • 54
0

In terms of learning how C works, as opposed to OO in C++, you might find it easier to take a short course in some other language that doesn't have an OO derivative -- say, Modula-2 (one of my favorites) or even BASIC (if you can still find a real BASIC implementation -- last time I wrote BASIC code it was with the QBASIC that came with DOS 5.0, later compiled in full Quick BASIC).

The methods you use to get things done in Modula-2 or Pascal (barring the strong typing, which protects against certain types of errors but makes it more complicated to do certain things) are exactly those used in non-OO C, and working in a language with different syntax might (probably will, IMO) make it easier to learn the concepts without your "programming reflexes" kicking in and trying to do OO operations in a nearly-familiar language.

Zeiss Ikon
  • 481
  • 4
  • 13