I'll start by saying it's a homework thing, but its got nothing to do with me learning C.
We are tasked to implement solutions to the Reader/Writer conflict using Semaphores and priority. Doing so in Java for the class.
The book we are working with, however uses C(I think) to handle their code examples. I'm not all that familiar with standard C and I can't figure out how to search existing literature for the answer I seek.
In the code:
semaphore x=1,wsem=1;
int readcount;
void reader()
{
While (true){
semWait(x);
readCount++;
if(readcount==1)
{
semWait(wsem);
}
semSignal(x);
READUNIT();
semWait(x);
readcount; /* <--- the questionable command */
if(readcount==0)
{
semSignal(wsem)
}
semSignal(x);
}
}
The line I have "starred" doesn't make any apparent sense. I appears to be simply stating or declaring the name of the variable. Is this some form of decrement I've never seen, or does this do something else? It seems like I'd be able to find it in some C-guide somewhere, but I haven't a clue what it's doing so I don't really know how to ASK what it's doing.
A variable name followed by a semicolon is a complete legal statement in C, but it does nothing. The form is rarely used, although it can be useful to suppress unused-variable warnings in some compilers.
From context, what it was probably supposed to be is readcount--;. That's the C decrement operator, undoing the readcount++ above.
Does your source also have the (erroneous) capital-W While and inconsistent spellings of readcount? If so, that's several bad typos in one short example and you should be suspicious of everything else in the book.
Related
Good morning, sir,
I use VisualStudio Code to code in C language. I recently discovered the Prettier extension for C, ( and "C/C++")
I saw that I could add an automatic indentation, when I added a ";" or when I saved with Ctrl+S.
with the addition of the lines ;
"editor.formatOnSave": true,
"editor.formatOnType": true
in visual studio's settings.json file.
Now, despite the almost perfect indentation, I wanted to make some adjustments such as the fact that after an initialization of variable type int
there's not a space but a tabulation, like this;
int x;
//rather than;
int x;
as well as for the type of functions
void ft_function(int x);
//rather than ;
void ft_function(int x);
(Because I have a standard to meet, and when I save or what, all the indentation of these variable initializations no longer meets my standard)
I don't know anything about json, and I've just discovered the function so I was wondering if the geniuses in the forum know anything about it, and if so how? At least some leads ^^
I found the setting "C_Cpp.clang_format_style": "{ BasedOnStyle: LLVM, AlignConsecutiveDeclarations: true }"
It works for my variables alignement but not for the functions. Therefore, my functions got auto-indent like this:
int ft_strlen(char *str) {
int i;
i = 0;
while (str[i])
i++;
return (i);
}
I would like something like:
int ft_strlen(char *str) {
int i;
i = 0;
while (str[i])
i++;
return (i);
}
The style you wish to implement, in use in some famous French programming schools such as Epita, Epitech and 42, is not widely implemented in programming environments. The original description, in French, is here.
Using tabs instead of spaces has fallen out of fashion because tab settings vary from one environment to another which breaks code and comment alignment, but for some reason, they are mandated by this document.
Aligning identifiers as they document is just an arbitrary constraint to teach programming students to pay great attention to detail and learn to follow local rules. At 42 for example, they run students' programs through a style checker and fail programs that break the strict presentation rules.
Among other surprising rules in effect there, programmers are taught to use while instead of for, which is highly questionable.
Similarly, I cannot think of a good reason to parenthesize the return value in the return statements.
Configuring Visual Studio Code to reformat your code for these rules does not seem easy without some extra code: if you find a utility to reformat the code to meet these rules, you might be able to register it as a custom filter. Search for moulinette on github... But if you cannot find one, write it yourself, it is a good exercise and will be so useful to your fellow students. You could even patch VSC.
Is it bad or good practice or maybe undefined behavior to re-assign function parameter inside function?
Let me explain what I'm trying to do with an example, here the function:
void
gkUpdateTransforms(GkNode *node /* other params */) {
GkNode *nodei;
if (!(nodei = node->chld))
return;
do {
/* do job */
nodei = nodei->next;
} while (nodei);
}
Alternative:
void
gkUpdateTransforms2(GkNode *node /* other params */) {
/* node parameter is only used here to get chld, not anywhere else */
if (!(node = node->chld))
return;
do {
/* do job */
node = node->next;
} while (node);
}
I checked assembly output and it seems same, we don't need to declare a variable in second one. You may ask what if parameter type changed but same condition would be same for first one, because it also need to be updated.
EDIT: Parameters are pass-by-value, and my intention is not edit pointer itself
EDIT2: What about recursive functions? What would happen if gkUpdateTransforms2 was recursive? I'm confused because function will call itself but I think in every call, parameters will be different stack
I have no idea why you think this would be undefined behavior - it is not. Mostly it is a matter of coding style, there's no obvious right or wrong.
Generally, it is good practice to regard parameters as immutable objects. It is useful to preserve an untouched copy of the input to the function. For that reason, it may be a good idea to use a local variable which is just a copy of the parameter. As you can see, this does not affect performance the slightest - the compiler will optimize the code.
However, it is not a big deal if you write to the parameters either. This is common practice too. Calling it bad practice to do so would be very pedantic.
Some pedantic coding styles make all function parameters const if they shouldn't be modified, but I personally think that's just obfuscation, which makes the code harder to read. In your case such pedantic style would be void gkUpdateTransforms(GkNode*const node). Not to be confused with const correctness, which is an universally good thing and not just a style matter.
However, there is something in your code which is definitely considered bad practice, and that is assignment inside conditions. Avoid this whenever possible, it is dangerous and makes the code harder to read. Most often there is no benefit.
The danger of mixing up = and == was noted early on in the history of C. To counter this, in the 1980s people came up with brain-damaged things like the "yoda conditions". Then around 1989 came Borland Turbo C which had a fancy warning feature "possible incorrect assignment". That was the death of the Yoda conditions, and compilers since then have warned against assignment in conditions.
Make sure that your current compiler gives a warning for this. That is, make sure not to use a worse compiler than Borland Turbo from 1989. Yes, there are worse compilers on the market.
(gcc gives "warning: suggest parentheses around assignment used as truth value")
I would write the code as
void gkUpdateTransforms(GkNode* node /* other params */)
{
if(node == NULL)
{
return ;
}
for(GkNode* i=node->chld; i!=NULL; i=i->next;)
{
/* do job */
}
}
This is mostly stylistic changes to make the code more readable. It does not improve performance much.
IMHO it is not exactly "bad" practice but it is worthwile to question oneself if there isn't a better way. About your analyzing the assembler output: it may serve as an interesting and educational look behind the curtain but you are ill advised to use this as an justification for optimization or worse, laziness in the source code. The next compiler or the next architecture may just render your musings completely invalid - my recommendation is to stay with Knuth here: "Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.".
In your code I think the decision is 50:50 with no clear winner. I would deem the node-iterator a concept of its own, justifying a separate programming construct (which in our case is just a variable) but then again the function is so simple that we don't win much in terms of clarity for the next programmer looking at your code, so we can very well live with the second version. If your function starts to mutate and grow over time, this premise may become invalid and we were better off the first version.
That said, I would code the first version like this:
void
gkUpdateTransforms(GkNode *node /* other params */) {
for (GkNode *nodei = node->chld; nodei != NULL; nodei = nodei->next) {
/* do job */
}
}
This is well defined and a perfectly good way to implement this behaviour.
The reason you might see it as an issue is the common mistake of doing the following:
int func(object a) {
modify a // only modifying copy, but user expects a to be modified
But in your case, you expect to make a copy of the pointer.
As long as it's passed by value, it can be safely treated as any other local variable. Not a bad practice in this scenario, and not undefined behaviour either.
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;
}
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.
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.
#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);
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.
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.
For my systems programming class we're doing a lot of programming in C and are required to error check most functions as we are currently learning to program with pthreads.
The reason I say this is not really homework, is that it is far above and beyond what is expected for this class. Simply checking each function individually is more than satisfactory. I just feel this is a time-consuming and messy method and hope for a neater solution.
I was wondering if anyone could show me how to write a function that takes any C function as a parameter, followed by all the required parameters for that function, along with a desired return value (in this case the correct one), and performs the following.
if(function_name(param1, param2, ...) != desired_return_value) {
fprintf(stderr, "program_name: function_name() failed\n");
perror("function_name(): ");
}
Is this possible? It's hardly required by our course, but it just irks me that virtually ever function I write has to have 4 lines of code to error check it. It makes it bloody hard to read.
Even some other suggestions would be good. I'm just trying to increase readability, so if this is totally the wrong direction, some correct direction would be much appreciated.
EDIT: This should compile under the gnu99 standard ideally :P
EDIT 2: In response to James McNellis:
The errors from our functions do not (I believe in this case), need to be handled. Notification only needs to be supplied. We have covered nothing on handling thread/process related errors (which is this subject in a nutshell).
Writing generic code in C without using macros isn't the easiest thing to do.
For a (very) basic solution using a variadic macro:
#define CALL_AND_CHECK(f, r, ...) \
do { \
if (f(__VA_ARGS__) != r) \
{ \
fprintf(stderr, "program_name: " #f "() failed\n"); \
perror(#f "(): "); \
} \
} while (0)
(See Why are there sometimes meaningless do/while and if/else statements in C and C++ macros? for why the "meaningless" do/while loop is used)
Note that printing out an error message and not actually handling the error is almost certainly a bad idea. Generally, different errors need to be handled in different ways, so generic code like this may not be particularly useful. If you don't want to try and recover from any of these errors, you could exit(), which might be okay for an assignment, though in a real-world program you wouldn't want to do that.
Sometimes I have to write code that alternates between doing things and checking for error conditions (e.g., call a library function, check its return value, keep going). This often leads to long runs where the actual work is happening in the conditions of if statements, like
if(! (data = (big_struct *) malloc(sizeof(*data)))){
//report allocation error
} else if(init_big_struct(data)){
//handle initialization error
} else ...
How do you guys write this kind of code? I've checked a few style guides, but they seem more concerned with variable naming and whitespace.
Links to style guides welcome.
Edit: in case it's not clear, I'm dissatisfied with the legibility of this style and looking for something better.
Though it pains me to say it, this might be a case for the never-popular goto. Here's one link I found on on the subject: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/
I usually write that code in this way:
data = (big_struct *) malloc(sizeof(*data));
if(!data){
//report allocation error
return ...;
}
err = init_big_struct(data);
if(err){
//handle initialization error
return ...;
}
...
In this way I avoid calling functions inside if and the debug is easier because you can check the return values.
Dont use assert in production code.
In debug mode, assert should never be used for something that can actually happen (like malloc returning NULL), rather it should be used in impossible cases (like array index is out of bounds in C)
Read this post for more.
One method which I used to great effect is the one used by W. Richard Stevens in Unix Network Programming (code is downloadable here. For common functions which he expects to succeed all the time, and has no recourse for a failure, he wraps them, using a capital letter (code compressed vertically):
void * Malloc(size_t size) {
void *ptr;
if ( (ptr = malloc(size)) == NULL)
err_sys("malloc error");
return(ptr);
}
err_sys here displays the error and then performs an exit(1). This way you can just call Malloc and know that it will error out if there is a problem.
UNP continues to be the only book I've where I think the author has code which checks the return values of all the functions which it's possible to fail. Every other book says "you should check the return values, but we'll leave that for you to do later".
I tend to
Delegate error checking to wrapper functions (like Stevens)
On error, simulate exceptions using longjmp. (I actually use Dave Hanson's C Interfaces and Implementations to simulate exceptions.)
Another option is to use Don Knuth's literate programming to manage the error-handling code, or some other kind of preprocessor. This option is available only if you get to set the rules for your shop :-)
The only grouping property of code like this is that there simply is an externally imposed sequence that it has to follow. This is why you put these allocations into one function, but this is a very weak commonality. Why some people recommend to abandon the scope advantages of nested if's is beyond my understanding. You are effectively trying to put lipstick on a pig (no insult intended) - the code's nature will never yield anything clean, the best you can do is to use the compilers help to catch (maintenance) errors. Stick with the if's IMHO.
PS: if I haven't convinced you yet: what will the goto-solution look like if you have to take ternary decisions? The if's will get uglier for sure, but the goto's???