What does operator ':=' mean? - c

I am trying to compile pthreads for MSVC2015 and found some strange code.
localPtr->wNodePtr->spin := PTW32_TRUE;
What is this line doing?

As others pointed out := is not a valid C-operator.
However, this "operator" := is found twice in the current "PThread for Windows" source release which seems to be as of v2.9.1.
Both occurencies appear in ptw32_OLL_lock.c, which proclaims to "implements extended reader/writer queue-based locks", but does not seem to be part of the pthread*.dll build, so the file ptw32_OLL_lock.c is not passed to the compiler.
Interesting enough the source file in question contains an int main() and is not in the testsub-directory.
All in all this seems to be alpha, beta or it's simply noise, so just delete it.

IIRC, C standard does not specify anything about := operator. So, most likely, it's not standard C.
However, AFAIK, some languages, which use the = as comparison operator, to separate the assignment from comparison, use := as assignment operator. [Example: Pascal, postgresql]
In some other cases, it carries a meaning that the variable is getting defined and assigned in the same step, to differentiate with normal assignment elsewhere. [Example: GO]

:= is not a valid operator in C.
It does however have use in other languages, for example ALGOL 68. Basically, for what you want to know, the := in this example is used to assign the variable PTW32_TRUE to localPty->wNodeptr->spin
This is done mostly to remove any ambiguity in code, as to avoid using '=' for assignment.

":=" is assignment to variable in Pascal syntax, while equality test is "="

Related

How to check if a variable has been initialized in C?

Is there a way to check if a variable has been initialized or not in C?
Consider the following example,
int main(){
int a = 3, b = 7, c;
if ( a > b )
c = a-b;
// Now, how can I check if the variable "c" has some value or not
// I don't want check like this,
// if ( isalpha(c) ) or if ( isdigit(c) )
// or anything similar to like that
}
In other words, does C has some function like defined in Perl. In Perl, I can simply do if (defined c)that would check if the variable is defined or not, and it'd return False for above example. How can I achieve the same in C?
C does not have this ability. You have two main options:
A sentinel value
For example, if you know that the value of c will never be negative, then initialize it to -1, and test that for that.
Add another variable
Create another variable bool we_set_c_to_something = false; and then set it to true when you write to c.
C is a compiled language which doesn't support runtime variable binding, while Perl is a interpreted language which support dynamic typing. So you can check the definition of a variable in Perl, but not in C.
When you declare a variable in C int c;, this variable c is defined but without initialization. The declaration and definition are in one statement.
The definition of a variable in C is not checked by code writer. The compilers do it for you. When compile and link your C code, the compiler will check all variable's definitions. An error will be invoked and the compiling or linking process will stop if there are undefined variables found in your code.
Hope this will make you distinguish the differences.
Wrong question. You're not asking whether the variable is defined. If the variable is not defined then compilation fails. Look up the difference between "declaration" and "definition". In the case of those local variables, you have defined the variable c.
What you're looking for is initialisation. Many compilers will warn you about using variables before they're initialised, but if you persist in running that code then the assumption is that you know better than the compiler. And at that point it's your problem. :) Some languages (e.g. Perl) have an extra flag that travels along with a variable to say whether it's been initialised or not, and they hide from you that there's this extra flag hanging around which you may or may not need. If you want this in C, you need to code it yourself.
Since C++ allows operator overloading, it's relatively easily to implement this in C++. Boost provides an "optional" template which does it, or you could roll your own if you want a coding exercise. C doesn't have the concept of operator overloading though (hell, the concept didn't really exist, and the compilers of the day probably couldn't have supported it anyway) so you get what you get.
Perl is a special case because it rolls the two together, but C doesn't. It's entirely possible in C to have variables which are defined but not initialised. Indeed there are a lot of cases where we want that to be the case, particularly when you start doing low-level access to memory for drivers and stuff like that.

Need help to understand the syntax in xv6 kernel

I am reading files of xv6 kernel and I cannot understand what the following means:
static int (*syscalls[])(void) = {
[SYS_fork] sys_fork,
[SYS_exit] sys_exit,
[SYS_wait] sys_wait,
[SYS_pipe] sys_pipe,
...
}
Can someone explain this to me? Especially what square brackets (e.g [SYS_fork]) mean.
Thank you
That code is making an array of function pointers, using an old alternative GNU extension for designated initialization.
Designated initializations is a feature that was added to C in C99 that lets you specify which array index to assign a specific value for arrays, so they need not be in order. The same feature exists for struct initializations where you can specify the specific field to assign a given value to.
The C99 syntax for array designated initializations is [index] = value. This code in particular though is using an older alternative syntax from GCC, which as per this document has been obsolete since GCC 2.5, in which there is no equals sign used.
In syscall.c the indices are specified using macros defined in syscall.h, the first of which is defined to 1 in syscall.h, et.c.
This is most likely a non-standard way of initializing an array of function pointers. The identifiers SYS_fork etc. are very likely macros or enum constants specifying the element index.
Another possibility is that this is not a C file, but is turned into a syntactically valid C file using some filtering tool prior to compilation.

Redefinition of Assignment Operator

It is in my understanding that several languages use := as the assignment operator. This is implemented to possibly avoid any confusion with the == operator. This seemed like a very valid point to me, so I was thinking of how to implement it in a language like C. Here is what I was thinking.
#define := =
// ... later on
int x := 4;
Although this would work (if the preprocessor supported that syntax), it would still allow me to get away with using the = operator. So my question is, Is there a way to "flag" a symbol or operator / Is there a way to prevent the use of some defined operator or symbol? Again, here is what I was thinking, but I don't know about the syntactical / semantical legality of this.
#undef =
#define := =
A macro name can only be an identifier. I'd be quite surprised if any C compiler accepted that definition. In principle, a compiler could accept it as a language extension, but gcc, for example, does not. Any conforming C compiler must at least issue a diagnostic.
You say it works; I'm frankly skeptical. What compiler are you using?
#undef =
Same problem.
I can see (and even agree with) your point that using := rather than = for the assignment operator would have been a better idea. But using the preprocessor to alter the language like this, even in cases where it works, is rarely a good idea.
C programmers know that = means assignment. Anyone reading your code can probably guess that := is meant to be assignment, but it would just make your code that much harder to read.
Standard C does not allow the '=' assignment operator to be undefined, or changed. However, the source code to several C compilers is available; and you are welcome to make your own modifications to your build of a C compiler. Including changing '=' to ':='. Good luck!
Good question, but don't do that. Your method results in bad readability.

In C, when is conditional "test ? : alt" form (empty true case) supported? [duplicate]

This question already has answers here:
?: ternary conditional operator behaviour when leaving one expression empty
(2 answers)
Closed 8 years ago.
In gcc, I can write foo ? : bar which is a shorthand form of foo ? foo : bar but I see that K&R doesn't mention it.
Is this something I should rely on, defined in some standard? Or just an (evil) gcc extension I should avoid?
This is a GCC extension by the name:
Conditionals with Omitted Operands.
It is not standard c.Using -pedantic flag for compilation will tell you so.
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression
    x ? : y
has the value of x if that is nonzero; otherwise, the value of y.
This example is perfectly equivalent to
    x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.
Is this something I should rely on, defined in some standard? Or just an (evil) gcc extension I should avoid?
Depends on your requirements, If your code does'nt need to run on any other compiler implementation other than GCC then you can use it. However, if your code is to build on across different other compiler implementations then you should not use it.
Anyhow, One should aim to write as much intuitive and readable code as possible given that I would always suggest avoiding such (ugly)constructs.
This is a GCC extension. It's not part of the C standard, but the GCC compiler lets you use it. See its documentation for details, and be mindful of its behavioural differences to the "equivalent" ternary expression.
This is an extension included in GCC.
It will not work if compiling with another compiler (that does not support that extension).
So I would recommend to avoid using this type of shortcut.
EDIT: As #KevinCox pointed out, even a DEFINE would not work (see 2nd comment below).

C++ assignment - stylish or performance?

Having been writing Java code for many years, I was amazed when I saw this C++ statement:
int a,b;
int c = (a=1, b=a+2, b*3);
My question is: Is this a choice of coding style, or does it have a real benefit? (I am looking for a practicle use case)
I think the compiler will see it the same as the following:
int a=1, b=a+2;
int c = b*3;
(What's the offical name for this? I assume it's a standard C/C++ syntax.)
It's the comma operator, used twice. You are correct about the result, and I don't see much point in using it that way.
Looks like an obscure use of a , (comma) operator.
It's not a representative way of doing things in C++.
The only "good-style" use for the comma operator might be in a for statement that has multiple loop variables, used something like this:
// Copy from source buffer to destination buffer until we see a zero
for (char *src = source, *dst = dest; *src != 0; ++src, ++dst) {
*dst = *src;
}
I put "good-style" in scare quotes because there is almost always a better way than to use the comma operator.
Another context where I've seen this used is with the ternary operator, when you want to have multiple side effects, e.g.,
bool didStuff = DoWeNeedToDoStuff() ? (Foo(), Bar(), Baz(), true) : false;
Again, there are better ways to express this kind of thing. These idioms are holdovers from the days when we could only see 24 lines of text on our monitors, and squeezing a lot of stuff into each line had some practical importance.
Dunno its name, but it seems to be missing from the Job Security Coding Guidelines!
Seriously: C++ allows you to a do a lot of things in many contexts, even when they are not necessarily sound. With great power comes great responsibility...
This is called 'obfuscated C'. It is legal, but intended to confuse the reader. And it seems to have worked. Unless you're trying to be obscure it's best avoided.
Hotei
Your sample code use two not very well known by beginners (but not really hidden either) features of C expressions:
the comma operator : a normal binary operator whose role is to return the last of it's two operands. If operands are expression they are evaluated from left to right.
assignment as an operator that returns a value. C assignment is not a statement as in other languages, and returns the value that has been assigned.
Most use cases of both these feature involve some form of obfuscation. But there is some legitimate ones. The point is that you can use them anywhere you can provide an expression : inside an if or a while conditional, in a for loop iteration block, in function call parameters (is using coma you must use parenthesis to avoid confusing with actual function parameters), in macro parameter, etc.
The most usual use of comma is probably in loop control, when you want to change two variables at once, or store some value before performing loop test, or loop iteration.
For example a reverse function can be written as below, thanks to comma operator:
void reverse(int * d, int len){
int i, j;
for (i = 0, j = len - 1 ; i < j ; i++, j--){
SWAP(d[i], d[j]);
}
}
Another legitimate (not obfuscated, really) use of coma operator I have in mind is a DEBUG macro I found in some project defined as:
#ifdef defined(DEBUGMODE)
#define DEBUG(x) printf x
#else
#define DEBUG(x) x
#endif
You use it like:
DEBUG(("my debug message with some value=%d\n", d));
If DEBUGMODE is on then you'll get a printf, if not the wrapper function will not be called but the expression between parenthesis is still valid C. The point is that any side effect of printing code will apply both in release code and debug code, like those introduced by:
DEBUG(("my debug message with some value=%d\n", d++));
With the above macro d will always be incremented regardless of debug or release mode.
There is probably some other rare cases where comma and assignment values are useful and code is easier to write when you use them.
I agree that assignment operator is a great source of errors because it can easily be confused with == in a conditional.
I agree that as comma is also used with a different meaning in other contexts (function calls, initialisation lists, declaration lists) it was not a very good choice for an operator. But basically it's not worse than using < and > for template parameters in C++ and it exists in C from much older days.
Its strictly coding style and won't make any difference in your program. Especially since any decent C++ compiler will optimize it to
int a=1;
int b=3;
int c=9;
The math won't even be performed during assignment at runtime. (and some of the variables may even be eliminated entirely).
As to choice of coding style, I prefer the second example. Most of the time, less nesting is better, and you won't need the extra parenthesis. Since the use of commas exhibited will be known to virtually all C++ programmers, you have some choice of style. Otherwise, I would say put each assignment on its own line.
Is this a choice of coding style, or does it have a real benefit? (I am looking for a practicle use case)
It's both a choice of coding style and it has a real benefit.
It's clearly a different coding style as compared to your equivalent example.
The benefit is that I already know I would never want to employ the person who wrote it, not as a programmer anyway.
A use case: Bob comes to me with a piece of code containing that line. I have him transferred to marketing.
You have found a hideous abuse of the comma operator written by a programmer who probably wishes that C++ had multiple assignment. It doesn't. I'm reminded of the old saw that you can write FORTRAN in any language. Evidently you can try to write Dijkstra's language of guarded commands in C++.
To answer your question, it is purely a matter of (bad) style, and the compiler doesn't care—the compiler will generate exactly the same code as from something a C++ programmer would consider sane and sensible.
You can see this for yourself if you make two little example functions and compile both with the -S option.

Resources