assigment statement can use an expression when declaring a variable?

V

vlsidesign

#include
int main(void)
{
float bread_price = 0.99;
int bread_count = 3;
float total_price = bread_count * bread_price; // this compiles okay

printf("total price is %.2f \n", total_price);

return 0;
}

I am a newbie, and my understanding is that, roughly speaking, an
expression is usually a mix of operators and operands, and computes a
value. When you use an assigment operator during a declaration and
initialize, you can use an expression on the right hand side of the
assigment state? I do this above, and it compiles okay and seems to
work.

I believe you are only supposed to do this if the variables in the
expression have already had been assigned values. I changed the above
to not have them initialized and it still compiled, and then printed
out 0.00. Maybe the below is not legal C syntax, but I have a smart
compiler?

float bread_price;
int bread_count;
float total_price = bread_count * bread_price; // illegal but compiler
is smart??

Maybe this is not C legal since I never gave 'bread_price' or
'bread_count' a value, but I just have a good compiler that
automatically give them a 0.0 and 0 value respectively. I believe also
I am supposed to use the cast since I am mixing datatypes.
 
V

vippstar

#include
int main(void)
{
float bread_price = 0.99;
int bread_count = 3;
float total_price = bread_count * bread_price; // this compiles okay

printf("total price is %.2f \n", total_price);

return 0;

}

I am a newbie, and my understanding is that, roughly speaking, an
expression is usually a mix of operators and operands, and computes a
An expression is anything that can be evaluated. f() is an expression
and so is foo.
Quoting 1 from 6.5 in the C99 standard:
An expression is a sequence of operators and operands that speciï¬es computation of a
value, or that designates an object or a function, or that generates side effects, or that
performs a combination thereof.
value. When you use an assigment operator during a declaration and
initialize, you can use an expression on the right hand side of the
assigment state? I do this above, and it compiles okay and seems to
work.
Yes. int n = 3, i = n; is valid.
I believe you are only supposed to do this if the variables in the
expression have already had been assigned values. I changed the above
to not have them initialized and it still compiled, and then printed
out 0.00. Maybe the below is not legal C syntax, but I have a smart
compiler?
No, you were just lucky.
You cannot use uninitialized objects in C. It's not valid. (strictly
speaking, it invokes undefined behavior, refer to the standard for
more information)
float bread_price;
int bread_count;
float total_price = bread_count * bread_price; // illegal but compiler
is smart??
Notice something here:
If the object resides in the global namespace or the static qualifier
is present, the object will be initialized to 0 (or NULL or if it's an
aggregate, every member/element to 0 recursively)
so
#include <stdio.h>
int a;
int main(void) { static int b; printf("(a+b)*2 = %d\n", (a+b)*2);
return 0; }
is fine for every conforming implementation and the results are
predictable.
Maybe this is not C legal since I never gave 'bread_price' or
'bread_count' a value, but I just have a good compiler that
automatically give them a 0.0 and 0 value respectively. I believe also
I am supposed to use the cast since I am mixing datatypes.
No, there is no need for that. I do not remember the formal term for
this, but int is promoted to double, (bread_price too).
 
R

Richard

An expression is anything that can be evaluated. f() is an expression
and so is foo.
Quoting 1 from 6.5 in the C99 standard:

Yes. int n = 3, i = n; is valid.

No, you were just lucky.
You cannot use uninitialized objects in C. It's not valid. (strictly
speaking, it invokes undefined behavior, refer to the standard for
more information)


What global statics?
 
E

Eric Sosman

vlsidesign said:
#include
int main(void)
{
float bread_price = 0.99;
int bread_count = 3;
float total_price = bread_count * bread_price; // this compiles okay

printf("total price is %.2f \n", total_price);

return 0;
}

I am a newbie, and my understanding is that, roughly speaking, an
expression is usually a mix of operators and operands, and computes a
value. When you use an assigment operator during a declaration and
initialize, you can use an expression on the right hand side of the
assigment state? I do this above, and it compiles okay and seems to
work.

Nomenclature: What you have above are not assignment
statements, but declarations that provide initializers for
the variables they declare. Yes, there are equal signs,
and yes, the things after the equal signs are expressions.
But the declarations are not statements, and the equal
signs are not operators. I'm being a little bit picky, but
my intent is honorable: I'm hoping to dispel some confusion,
and perhaps steer you toward the relevant sections (note the
plural) of your C textbook. Now, on with the show:
I believe you are only supposed to do this if the variables in the
expression have already had been assigned values.

The general rule is that you cannot make use of the value
of a variable that has not yet been given a value. Well, you
can try it, but there's no telling what will happen: You might
get a zero or NULL or some such, or you might get some kind of
random garbage, or your program might crash, or your computer
might melt into a sticky mound of chocolate pudding. Some of
these outcomes may be rather unlikely, but the point is this:
If you try to use the value of a variable that doesn't yet have
one, all bets are off.

A variable declared "at file scope" (outside of any function)
or a variable declared with the `static' keyword can never be in
this indeterminate, uninitialized state. If you don't provide
explicit initializers, such variables are silently initialized
to zero or NULL -- or to lots of zeroes and NULLs if they are
arrays or structs. But "automatic" variables -- roughly, those
declared inside functions and without `static' -- do not get
such treatment; you must initialize them and/or assign values
to them before you try to use their values. The same goes for
data allocated dynamically by malloc() and realloc().
I changed the above
to not have them initialized and it still compiled, and then printed
out 0.00. Maybe the below is not legal C syntax, but I have a smart
compiler?

"Dumb compiler," I'd call it. A smart compiler would notice
the infraction and burp up a warning that you've attempted an
unreliable and unpredictable operation. Many compilers support
command-line flags or similar controls that influence their
level of smartness; if you're using the popular gcc compiler
I'd suggest invoking it as

gcc -W -Wall -ansi -pedantic -O2 ...
[...] I believe also
I am supposed to use the cast since I am mixing datatypes.

Most uses of casts are mistakes. Not all, obviously --
if that were so, there'd be no reason for the language to
offer them! But it is certainly not necessary to use a cast
when multiplying a float by an int; C's built-in rules for
reconciling mixed types handle it for you.
 
K

Kaz Kylheku

#include
int main(void)
{
float bread_price = 0.99;
int bread_count = 3;
float total_price = bread_count * bread_price; // this compiles okay

printf("total price is %.2f  \n", total_price);

return 0;

}

I am a newbie, and my understanding is that, roughly speaking, an
expression is usually a mix of operators and operands, and computes a
value. When you use an assigment operator during a declaration and
initialize, you can use an expression on the right hand side of the
assigment state? I do this above, and it compiles okay and seems to
work.

The ``= expression'' syntax in a declaration isn't an assignment
statement. It's an initializer. This distinction is important because
initialization doesn't necessarily occur in the order that it appears.

For instance if you have

{
static int x = 3;
x = 42;
}

The initialization happens only once, prior to program startup!
Whereas the assignment x = 42 takes place whenever the block is
executed.

Initialization means ``arrange for this object to have an initial
value, with a timing that depends on the storage class'', whereas
assignment means ``stick a value into this object now''.

In short, initialization isn't assignment.

An object that is initialized never exists in a previous state when it
is not initialized. The object and the value come into existence at
the same time.

Some objects can't be assigned to (e.g. constants), yet they can be
initialized.

// obviously not assignment
const int x = 3;
I believe you are only supposed to do this if the variables in the
expression have already had been assigned values. I changed the above
to not have them initialized and it still compiled, and then printed
out 0.00. Maybe the below is not legal C syntax, but I have a smart
compiler?

In what way is it smart to deduce that the value of a multiplication
of two completely indeterminate values is zero?
float bread_price;
int bread_count;
float total_price = bread_count * bread_price; // illegal but compiler
is smart??

If this translates without a diagnostic, your compiler is not smart at
all, but very dumb. Or maybe you just aren't asking it to produce
enough diagnostics.

For every compiler that you use, you should find out two things: 1)
how to make that compiler behave as closely as possible to the ISO C
standard (so that it suppresses all non-conforming extensions and
issues all required diagnostics) and 2) how to enable useful
additional diagnostics to catch as many errors as possible.
Maybe this is not C legal since I never gave 'bread_price' or
'bread_count' a value

It's undefined behavior, meaning that the behavior can be anything:
- the program may fail to translate at all
- the situation at run time can be ignored such that computation can
continues with incorrect values,
- or the program can terminate with or without a diagnostic, normally
or abnormally.
, but I just have a good compiler that
automatically give them a 0.0 and 0 value respectively. I believe also
I am supposed to use the cast since I am mixing datatypes.

Many constructs in C perform conversions implicitly. Casts are needed
when a needed conversion doesn't take place, or the implied conversion
is possible, but requires a diagnostic that is overcome with a cast.

For instance if you divide two operands, both integers, integer
division takes place producing an integral results. If you want a
floating-point result, you must cast at least one of the operands to a
floating type.

Certain conversions among pointer types won't take place without a
cast, because the results of such conversions have potential safety
issues.
 
D

David Thompson

Aside: noone (that I saw) commented on this obviously wrong #include.

Aside: it is usually a bad idea to use floating-point, and especially
'float' (single precision), to represent 'fractional' money amounts
such as dollars and cents, assuming that's what you have here.
Computer floating-point today is universally binary (although not
actually required by C) and cannot represent decimal amounts exactly,
so unless you are VERY careful you will sometimes get wrong results
that seem random and make you look like a cheat or even a crook.
(There are some specialized areas of finance where FP is the right
answer, or at least a right answer, but you need a lot more domain
knowledge than '3 loaves of bread' to recognize them safely.)
Nomenclature: What you have above are not assignment
statements, but declarations that provide initializers <snip>
Yes.


The general rule is that you cannot make use of the value
of a variable that has not yet been given a value. <snip>
A variable declared "at file scope" (outside of any function)
or a variable declared with the `static' keyword can never be in
this indeterminate, uninitialized state. <snip>

Yes. And since we're explaining the distinction, I would add that
initializers for static-duration variables have to be *constant*
expressions; they cannot involve variables (even const variables!) or
function calls. This is because they are evaluated at compile time.
(Strictly speaking the standard only requires them to be done before
run time, but the restrictions are designed to allow compile time, and
that's easier to implement, and conventional, and understood.)

Also, it wasn't at issue here, but you can never initialize an array
with a single expression, only with a braced list. In C90 the elements
of that list must be constant in all cases; in C99 you may have
nonconstant (run time) expressions in the list for an auto-duration
array. In C90 you can initialize a struct with a single expression
only by using a function call, and thus only for an auto-duration
variable; in C99 you can also use a compound literal, which is
technically a single expression, but it is always longer than the
equivalent braced list and hence silly.

<snip rest>
- formerly david.thompson1 || achar(64) || worldnet.att.net
 
K

Keith Thompson

David Thompson said:
Aside: noone (that I saw) commented on this obviously wrong #include.


Aside: it is usually a bad idea to use floating-point, and especially
'float' (single precision), to represent 'fractional' money amounts
such as dollars and cents, assuming that's what you have here.
Computer floating-point today is universally binary (although not
actually required by C) and cannot represent decimal amounts exactly,
so unless you are VERY careful you will sometimes get wrong results
[snip]

It's not quite *universally* binary. There are proposals for decimal
floating-point (using, if I recall correctly, 10 bits to represent 3
decimal digits, so it's more bit-efficient that BCD). IBM has at
least one hardware implementation, and there's a proposed ISO C
extension.

But your general point is quite correct.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,591
Members
45,103
Latest member
VinaykumarnNevatia
Top