Some code I have inherited contains a macro like the following:
#define setState(state, newstate) \
(state >= newstate) ? \
(fprintf(stderr, "Illegal state\n"), TRUE) : \
(state = newstate, FALSE)
This macro is called like this:
setState(state, ST_Used);
I understand that the macro prints an error message unless the new
state is greater than the old state. I don't understand the TRUE and
FALSE bits.
It looks like the comma operator causes the macro to evaluate to TRUE
or FALSE. Am I right?
What is the result of the macro evaluating to TRUE or FALSE?
It's hard to know what the original programmer was thinking, but could
he have been intending the macro to be used as a condition?
if (setState(state, ST_Used))
do something...
Any thoughts about why the comma operator is being used will be
appreciated.
Thanks,
Shawn 11 2318
On Tue, 29 Jun 2004 11:42:36 -0700, Shawn Odekirk wrote: Some code I have inherited contains a macro like the following:
#define setState(state, newstate) \ (state >= newstate) ? \ (fprintf(stderr, "Illegal state\n"), TRUE) : \ (state = newstate, FALSE)
This macro is called like this:
setState(state, ST_Used);
I understand that the macro prints an error message unless the new state is greater than the old state. I don't understand the TRUE and FALSE bits. It looks like the comma operator causes the macro to evaluate to TRUE or FALSE. Am I right?
No.
The comma separates two arguments to a macro called state and newstate
The second line is a comparison which evaluates to true if state is
greater than or equal to newstate otherwise it is false
The macro is built on a old device called a tri-graph which works like
this
<some expresion> ? statement1 : statement2
The expresion returns a value (true or false) and if it is true
statement 1 is executed. If it is false statement 2 is executed.
All statements return a value whether or not you use it. in a comma
seperated list of statements the result of the statement is the result of
the last statement so the original programmer is 'returning' either true
or false most probably to use in conditional tests as you suggest below.
What is the result of the macro evaluating to TRUE or FALSE? It's hard to know what the original programmer was thinking, but could he have been intending the macro to be used as a condition?
if (setState(state, ST_Used)) do something...
Any thoughts about why the comma operator is being used will be appreciated.
The comma is used here to make sure the return value is of the correct
type. Any statements seperated by a comma are executed in order but the
return value is the value of the last statement and also of that type.
The macro would work with any numerical type but because of the
comma returns a boolean very useful if you want to do ---
/* snipity snip*/
boolean flag;
..
..
..
flag=setState(var1, var5); Thanks, Shawn
P.S. False is '0', true= non zero result
OK
Trevor sh***********@fkilogistex.com (Shawn Odekirk) wrote in message news:<d2**************************@posting.google. com>... Some code I have inherited contains a macro like the following:
#define setState(state, newstate) \ (state >= newstate) ? \ (fprintf(stderr, "Illegal state\n"), TRUE) : \ (state = newstate, FALSE)
This macro is called like this:
setState(state, ST_Used);
I understand that the macro prints an error message unless the new state is greater than the old state. I don't understand the TRUE and FALSE bits. It looks like the comma operator causes the macro to evaluate to TRUE or FALSE. Am I right? What is the result of the macro evaluating to TRUE or FALSE? It's hard to know what the original programmer was thinking, but could he have been intending the macro to be used as a condition?
if (setState(state, ST_Used)) do something...
Any thoughts about why the comma operator is being used will be appreciated.
1. Probably so that it can be used in an if or while statement
2. TRUE, FALSE, and the type of state are undefined in the snippet,
if the type of "state" is not an int, or freely convertible to int,
then some compilers may generate an error or warning (disclaimer, I
don't have a copy of the standard). I believe that both operands of a
?: operator must have the same type (but I may be wrong).
On 29 Jun 2004 11:42:36 -0700, sh***********@fkilogistex.com (Shawn
Odekirk) wrote: Some code I have inherited contains a macro like the following:
#define setState(state, newstate) \ (state >= newstate) ? \ (fprintf(stderr, "Illegal state\n"), TRUE) : \ (state = newstate, FALSE)
This macro is called like this:
setState(state, ST_Used);
I understand that the macro prints an error message unless the new
No, the macro doesn't print anything.
state is greater than the old state. I don't understand the TRUE and FALSE bits. It looks like the comma operator causes the macro to evaluate to TRUE or FALSE. Am I right?
Macros are inputs to the preprocessor. The only thing they evaluate
to is the substituted text which is then passed to the compiler. When
used as in your example, the macro evaluates to
(state >= ST_Used) ?
(fprintf(...), TRUE) :
(state = ST_Used, FALSE);
TRUE and FALSE are probably also macros and should be defined prior to
setState.
Now, if this code is ever executed, then one of two things will
happen:
The string will be sent to stderr and the expression will evaluate
to TRUE (which I would expect to be 1).
The value in state will be changed and the expression will
evaluate to FALSE (which I would expect to be 0).
What is the result of the macro evaluating to TRUE or FALSE? It's hard to know what the original programmer was thinking, but could he have been intending the macro to be used as a condition?
if (setState(state, ST_Used)) do something...
A reasonable assumption. Not necessarily true but reasonable. If you
have reason to believe the original author was competent, it might
even be probable. But then we have to ask why he didn't leave any
documentation so you wouldn't have to guess. Do you see any code that
looks like this? How often does he invoke the macro? Any thoughts about why the comma operator is being used will be appreciated.
Since the macro could have just as easily evaluate to an if-then-else,
my *guess* is that he thought he was being clever. If you really need
to know, you could ask in one of the ESP newsgroups but here it is
only a guess.
<<Remove the del for email>>
Trevor Pearson <tr***********@haven.demon.co.uk> writes: On Tue, 29 Jun 2004 11:42:36 -0700, Shawn Odekirk wrote:
Some code I have inherited contains a macro like the following:
#define setState(state, newstate) \ (state >= newstate) ? \ (fprintf(stderr, "Illegal state\n"), TRUE) : \ (state = newstate, FALSE)
This macro is called like this:
setState(state, ST_Used);
I understand that the macro prints an error message unless the new state is greater than the old state. I don't understand the TRUE and FALSE bits. It looks like the comma operator causes the macro to evaluate to TRUE or FALSE. Am I right? No.
Yes, he's right.
The comma separates two arguments to a macro called state and newstate
Yes, the comma on the first line (the one starting with "#define")
separates the two parameters of the setState macro, but that's not the
comma operator the OP was asking about.
The second line is a comparison which evaluates to true if state is greater than or equal to newstate otherwise it is false
Right.
The macro is built on a old device called a tri-graph which works like this <some expresion> ? statement1 : statement2
That's a trinary expression, or a conditional expression. (A trigraph
is something else entirely.) All three operands are expressions, not
statements. The distinction between statements and expressions is
very important.
The expresion returns a value (true or false) and if it is true statement 1 is executed. If it is false statement 2 is executed.
Replace "statement" with "expression", and "executed" with
"evaluated", and that's essentially correct.
All statements return a value whether or not you use it. in a comma seperated list of statements the result of the statement is the result of the last statement so the original programmer is 'returning' either true or false most probably to use in conditional tests as you suggest below.
Expressions return (or, more accurately, yield) values; statements do
not. Statements are not separated by commas.
In the third and fourth lines of the macro definition (the second and
third operands of the "?:" operator), the comma is being used as a
comma operator. This operator takes two operands. The left operand
is evaluated (presumably for side effects) and its result is
discarded, then the right operand is evaluted and its result becomes
the result of the comma operator.
The ?: operator is analagous to an if-else statement, and a comma
operator is analagous to a pair of consecutive statements; the
difference is that the operators apply to expressions, not to
statements. These operators are commonly used in definitions of
macros that are intended to be used as expressions (which can't
contain statements).
Here's the macro definition again:
#define setState(state, newstate) \
(state >= newstate) ? \
(fprintf(stderr, "Illegal state\n"), TRUE) : \
(state = newstate, FALSE)
though to avoid possible operator precedence problems I'd probably
write it like this:
#define setState(state, newstate) \
(((state) >= (newstate)) ? \
(fprintf(stderr, "Illegal state\n"), TRUE) : \
((state) = (newstate), FALSE))
If this were written as a function, it might look like this:
int setState(int *state, int newstate)
{
if (*state >= newstate) {
fprintf(stderr, "Illegal state\n");
return TRUE;
}
else {
*state = newstate;
return FALSE;
}
}
In the macro, state is modified, so I made it a pointer argument in
the function.
Presumably it was implemented as a macro to avoid the overhead of a
function call. That's not always a good tradeoff. Many optimizing
compilers support inline functions, either explicitly or implicitly.
All this assumes appropriate definitions for FALSE and TRUE.
If the macro is invoked, or the function is called, in a context like
setState(state, ST_Used);
the result (either FALSE or TRUE) is discarded. This may or may not
be a bad idea (it can mask errors).
--
Keith Thompson (The_Other_Keith) ks***@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.
Keith Thompson wrote: Trevor Pearson <tr***********@haven.demon.co.uk> writes:
[snip]The macro is built on a old device called a tri-graph which works like this <some expresion> ? statement1 : statement2
That's a trinary expression, or a conditional expression. (A trigraph is something else entirely.) All three operands are expressions, not statements. The distinction between statements and expressions is very important.
Nit: It's a *ternary* expression.
HTH,
--ag
--
Artie Gold -- Austin, Texas
"What they accuse you of -- is what they have planned."
Artie Gold <ar*******@austin.rr.com> writes: Keith Thompson wrote: Trevor Pearson <tr***********@haven.demon.co.uk> writes: [snip]The macro is built on a old device called a tri-graph which works like this <some expresion> ? statement1 : statement2 That's a trinary expression, or a conditional expression. (A trigraph is something else entirely.) All three operands are expressions, not statements. The distinction between statements and expressions is very important.
Nit: It's a *ternary* expression. HTH,
The standard doesn't refer to it as either trinary or ternary (it does
use the word "ternary" a couple of times, but not in reference to the
conditional operator). But yes, "ternary" is probably a better term.
Thanks.
The standard refers to operators that take two operands as "binary
operators". Is there a word that is to "binary" as "ternary" is to
"trinary"?
--
Keith Thompson (The_Other_Keith) ks***@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.
Keith Thompson <ks***@mib.org> wrote in message news:<ln************@nuthaus.mib.org>... Trevor Pearson <tr***********@haven.demon.co.uk> writes: On Tue, 29 Jun 2004 11:42:36 -0700, Shawn Odekirk wrote:
The macro is built on a old device called a tri-graph which works like this <some expresion> ? statement1 : statement2
That's a trinary expression, or a conditional expression. (A trigraph is something else entirely.) All three operands are expressions, not statements. The distinction between statements and expressions is very important.
The expresion returns a value (true or false) and if it is true statement 1 is executed. If it is false statement 2 is executed.
Replace "statement" with "expression", and "executed" with "evaluated", and that's essentially correct.
Something that evaluates to void is a expression ?
because i tried compiling this code and i succeded without
warning
void f0()
{
}
void f1()
{
}
//
<expression> ? f0() : f1();
Dario wrote: Keith Thompson <ks***@mib.org> wrote in message news:<ln************@nuthaus.mib.org>...
Trevor Pearson <tr***********@haven.demon.co.uk> writes:
On Tue, 29 Jun 2004 11:42:36 -0700, Shawn Odekirk wrote:
The macro is built on a old device called a tri-graph which works like this <some expresion> ? statement1 : statement2
That's a trinary expression, or a conditional expression. (A trigraph is something else entirely.) All three operands are expressions, not statements. The distinction between statements and expressions is very important.
The expresion returns a value (true or false) and if it is true statement 1 is executed. If it is false statement 2 is executed.
Replace "statement" with "expression", and "executed" with "evaluated", and that's essentially correct.
Something that evaluates to void is a expression ? because i tried compiling this code and i succeded without warning
void f0() { } void f1() { } //
<expression> ? f0() : f1();
Every C expression has a type. Most C expressions
also produce values, but expressions of type `void' are
an exception: the `void' type cannot express any value.
An expression of `void' type, even though it produces no
value, is an expression nonetheless.
`void' is, obviously, a peculiar beast. It is a type,
but cannot express values. It is a type, yet one cannot
create objects of that type. It is an incomplete type
that cannot be completed. Given all these oddities one
might wonder why `void' should be considered a "type" at
all, and many languages other than C do perfectly well
without a `void'-like notion at all. But such languages
usually have other features that make `void' unnecessary:
they may distinguish between "function" and "subroutine,"
or they may allow an expression to produce a special value
like "nil." C lacks "nil" and has no "subroutine" or
"procedure" or "call" statement, and it seems to me this
is why C has `void'.
-- Er*********@sun.com da************@inwind.it (Dario) wrote: Keith Thompson <ks***@mib.org> wrote in message news:<ln************@nuthaus.mib.org>... Trevor Pearson <tr***********@haven.demon.co.uk> writes:
<snip > The expresion returns a value (true or false) and if it is true > statement 1 is executed. If it is false statement 2 is executed. Replace "statement" with "expression", and "executed" with "evaluated", and that's essentially correct.
Something that evaluates to void is a expression ?
Yes, of course; random examples: (void)666, free(NULL), ...
because i tried compiling this code and i succeded without warning
void f0() { } void f1() { } //
<expression> ? f0() : f1();
(Assuming <expression> is an actual expression that meets the
requirements for a logical-OR-expression, and the last line appears
in a function body:) A compiler diagnostic is not required, since
this is perfectly valid C code, which is essentially equivalent to:
if ( <expression> )
f0();
else
f1();
In other words, the second or third operand of the conditional
operator is evaluated only for its side effects, not for its
value.
Albeit, if you try to assign the non-existent value of the result
to an object, you invoke undefined behaviour:
int i = ( 6 * 9 == 42 ) ? f0() : f1(); /* WRONG! */
Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html re********@yahoo.com (red floyd) wrote:
<snip> I believe that both operands of a ?: operator must have the same type
Not necessarily, consider:
ISO/IEC 9899:1999
6.5.15 Conditional operator
Syntax
1 conditional-expression:
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
Constraints
2 The first operand shall have scalar type.
3 One of the following shall hold for the second and third operands:
- both operands have arithmetic type;
- both operands have the same structure or union type;
- both operands have void type;
- both operands are pointers to qualified or unqualified versions
of compatible types;
- one operand is a pointer and the other is a null pointer
constant;
or
- one operand is a pointer to an object or incomplete type and the
other is a pointer to a qualified or unqualified version of void.
Regards
--
Irrwahn Grausewitz (ir*******@freenet.de)
welcome to clc: http://www.ungerhu.com/jxh/clc.welcome.txt
clc faq-list : http://www.faqs.org/faqs/C-faq/faq/
clc OT guide : http://benpfaff.org/writings/clc/off-topic.html
On Wed, 30 Jun 2004 05:48:06 GMT, Keith Thompson <ks***@mib.org>
wrote: Artie Gold <ar*******@austin.rr.com> writes: Keith Thompson wrote: [use of ?:]'s a trinary expression, or a conditional expression. <snip> Nit: It's a *ternary* expression.
The standard doesn't refer to it as either trinary or ternary (it does use the word "ternary" a couple of times, but not in reference to the conditional operator). But yes, "ternary" is probably a better term. Thanks.
The standard refers to operators that take two operands as "binary operators". Is there a word that is to "binary" as "ternary" is to "trinary"?
APL called 1- and 2-operand operators monadic and dyadic, both I
believe from Greek. Which has the advantage of leaving binary to mean
base-2 arithmetic, and possibly also Boolean logic but C uses bitwise
for that. APL classically also used niladic for 0-operands, though I
have recently been told that is inconsistent and anadic is better.
- David.Thompson1 at worldnet.att.net This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Paul Davis |
last post by:
I'd like to overload 'comma' to define a concatenation operator for
integer-like classes. I've got some first ideas, but I'd appreciate a
sanity check. The concatenation operator needs to so...
|
by: Derek |
last post by:
I came upon the idea of writting a logging class that
uses a Python-ish syntax that's easy on the eyes (IMO):
int x = 1;
double y = 2.5;
std::string z = "result";
debug = "Results:", x, y,...
|
by: Bo Sun |
last post by:
hi,
suppose I have the following expression (all variables are of integer
type)
result = (first = 2, second = first + 1, third = second + 1);
what is the value of result?
1) result is 4....
|
by: benben |
last post by:
I am looking for a good example of overloading operator , (operator comma)
Any suggestions?
Ben
|
by: Koster |
last post by:
Hi folks,
As I understand it, amongst other things, the comma operator may be used to
cause any number of expressions to be evaluated (who's results are thrown
away except the last) where only...
|
by: G Patel |
last post by:
Hi,
I've read a book on C, and I understand how comma operators work, but
my book didn't say that the comma operators between function arguments
were not really comma operators (even though it...
|
by: siliconwafer |
last post by:
Hi,
In case of following expression:
c = a && --b;
if a is 0,b is not evaluated and c directly becomes 0.
Does this mean that && operator is given a higher precedence over
'--'operator?
as...
|
by: pedroalves |
last post by:
Hi all,
This is not a question about how to #define COMMA ,
Please keep reading.
Recently in binutils, we introduced a macro like this:
#define STRING_COMMA_LEN(STR) \
(STR), ((STR) ?...
|
by: Lighter |
last post by:
In 5.3.3.4 of the standard, the standard provides that "The lvalue-to-
rvalue(4.1), array-to-pointer(4.2),and function-to-pointer(4.3)
standard conversions are not applied to the operand of...
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: Aliciasmith |
last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
|
by: NeoPa |
last post by:
Hello everyone.
I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report).
I know it can be done by selecting :...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM)
Please note that the UK and Europe revert to winter time on...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
| |