Structure without a tag

  • Thread starter МакÑим Фомин
  • Start date
Ð

МакÑим Фомин

Consider this code:

struct
{
int x;
int y;
} one;

struct
{
int x;
int y;
} two;

int main(void)
{
one.x = one.y = 6;
one = two;
return 0;
}

Compiler rejects assignment of first structure to second
("incompatible types when assigning to type ‘struct <anonymous>’ from
type ‘struct <anonymous>’").

It seems to me that objects one and two have type struct {int x; int
y} and therefore their types are equal.

If not, which type they have?
 
E

Eric Sosman

Consider this code:

struct
{
int x;
int y;
} one;

struct
{
int x;
int y;
} two;

int main(void)
{
one.x = one.y = 6;
one = two;
return 0;
}

Compiler rejects assignment of first structure to second
("incompatible types when assigning to type ‘struct<anonymous>’ from
type ‘struct<anonymous>’").

It seems to me that objects one and two have type struct {int x; int
y} and therefore their types are equal.

If not, which type they have?

The language Standard states the rules for "type compatibility,"
and according to those rules the types of `one' and `two' are not
compatible. Yes, they look alike. But they are not compatible, and
you cannot assign from one to the other.

This is usually a Good Thing, because the fact that the two types
have the same representation is just a coincidence. There are many
different kinds of things you might represent with a pair of ints:
a point in a two-dimensional grid, the scores of each side in a
football match, the number of votes for and against a proposed law,
the number of axles and weight in tonnes of a truck, ... Even though
both representations consist of two ints, it would probably be a mistake
to store a vote tally in the description of a truck!

Or, consider

#include <limits.h>
struct {
int x, y;
} one;
struct {
#if INT_MAX >= 1000000
int x, y;
#else
long x, y;
#endif
} two;

Depending on the platform, `one' and `two' might or might not have
the same representation. If the representations happen to agree on
Platform X, do you think the assignment `one = two' is a good idea?
The programmer quite clearly has different expectations about what
can be stored in `one.x' and `two.x', even if the representations
sometimes turn out to be the same.
 
K

Keith Thompson

МакÑим Фомин said:
Consider this code:

struct
{
int x;
int y;
} one;

struct
{
int x;
int y;
} two;

int main(void)
{
one.x = one.y = 6;
one = two;
return 0;
}

Compiler rejects assignment of first structure to second
("incompatible types when assigning to type ‘struct <anonymous>’ from
type ‘struct <anonymous>’").

It seems to me that objects one and two have type struct {int x; int
y} and therefore their types are equal.

If not, which type they have?

If you had declared them with distinct tags:

struct foo { int x; int y; } one;
struct bar { int x; int y; } two;

they'd be of distinct and incompatible types, "struct foo" and "struct
bar".

Omitting the tags doesn't make them compatible.

If you want "one" and "two" to have compatible types, it's easy enough
to declare them that way, either:

struct { int x; int y; } one, two;

or

struct foo { int x; int y; };
struct foo one;
struct foo two;
 
E

Eric Sosman

That seems to me to be strange reasoning; after all, there are many
different kinds of things you might represent with a single of int: a
person's height, a person's weight. It would probably be a mistake to
store a height in a weight!

True. C's built-in types offer no protection against that
sort of blunder. But derived types offer a little more, and it's
better to have a little more protection than none at all.
 
J

Jean-Christophe

On 15 oct, 22:20, МакÑим Фомин
struct
{ int x;
   int y;
}  one;

struct
{ int x;
   int y;
}  two;


They are exacltly the same, so you don't
need two different structure declaration.
int main(void)
{
   one.x = one.y = 6;
   one = two;
   return 0;
}

Nah :


int main(void)
{
one.x = one.y = 6;

memcpy( &two, &one, sizeof(two) );

return 0;
}
 
K

Keith Thompson

Frederick Williams said:
That seems to me to be strange reasoning; after all, there are many
different kinds of things you might represent with a single of int: a
person's height, a person's weight. It would probably be a mistake to
store a height in a weight!

Yes, and there are languages that provide exactly that kind of
protection. C isn't one of them.

You could, however, declare a struct type containing an int:

struct height { int h; };
struct weight { int w; };
 
J

Jorgen Grahn

That seems to me to be strange reasoning; after all, there are many
different kinds of things you might represent with a single of int: a
person's height, a person's weight. It would probably be a mistake to
store a height in a weight!

In a sense, it's the lack of an easy[1] way to create distinct types from
these ints that is strange!

/Jorgen
[1] Others gave the not-so-easy recipe for doing it: putting the int
inside a struct.
 
E

Eric Sosman

That seems to me to be strange reasoning; after all, there are many
different kinds of things you might represent with a single of int: a
person's height, a person's weight. It would probably be a mistake to
store a height in a weight!

In a sense, it's the lack of an easy[1] way to create distinct types from
these ints that is strange!

[1] Others gave the not-so-easy recipe for doing it: putting the int
inside a struct.

It's easy enough to make the struct, but less convenient to
use it once made. (Cue someone's rant about operator overloading.)

Note that you probably don't want to forbid all mixtures of
types, even in simple arithmetic. For example,

weight / (height * height * height) * shapeFactor

might be a perfectly valid calculation of density.
 
B

BartC

Eric Sosman said:
On Sun, 2011-10-16, Frederick Williams wrote:
In a sense, it's the lack of an easy[1] way to create distinct types from
these ints that is strange!

[1] Others gave the not-so-easy recipe for doing it: putting the int
inside a struct.

It's easy enough to make the struct, but less convenient to
use it once made. (Cue someone's rant about operator overloading.)

Note that you probably don't want to forbid all mixtures of
types, even in simple arithmetic. For example,

weight / (height * height * height) * shapeFactor
might be a perfectly valid calculation of density.

Well, it's usually height*width*depth, with these 3 quantities having type
Length.

But trying to do this stuff properly in a language (and with different
Length quantities perhaps each expressed in different units) usually turns
into a nightmare. It's a lot easier to just have a single type Number..
 
J

James Kuyper

On 10/16/2011 06:29 PM, Eric Sosman wrote:
....
Note that you probably don't want to forbid all mixtures of
types, even in simple arithmetic. For example,

weight / (height * height * height) * shapeFactor

might be a perfectly valid calculation of density.

Unit-based constraints don't come into play in multiplication and
division. The result simply has units that are determined by the units
of the operands. The relevant constraints apply to addition and
subtraction, comparison (for order or for equality), and assignment - It
only makes sense to perform any of those operations between operands
that have the same units.
 
B

Ben Pfaff

BartC said:
But trying to do this stuff properly in a language (and with different
Length quantities perhaps each expressed in different units) usually
turns into a nightmare. It's a lot easier to just have a single type
Number..

Units work admirably well on the HP-48 series of calculators. In
college, I attached units to all my calculations on the HP-48 GX.
It was very helpful because I tended to find that my answers were
wrong if the units attached to them were not what I expected.
 
K

Kaz Kylheku

On 10/16/2011 06:29 PM, Eric Sosman wrote:
...

Unit-based constraints don't come into play in multiplication and
division. The result simply has units that are determined by the units
of the operands. The relevant constraints apply to addition and
subtraction, comparison (for order or for equality), and assignment - It
only makes sense to perform any of those operations between operands
that have the same units.

But constraints could enter into multiplication. You could have a rule base
which gives valid combinations of units, making it an error to, say, multiply
the number of calories in a cookie by the voltage across a resistor.

Furthermore, you might want rules which recognize combinations of units as
being equivalent to some other combinations of units (or as being named units
in their own right).

Suppose A arises as the result of multiplying Newtons by meters, and B arises
as a result of multiplying kilograms, meters and dividing by seconds squared.
You might want to be able to add these together.
 
J

James Kuyper

But constraints could enter into multiplication. You could have a rule base
which gives valid combinations of units, making it an error to, say, multiply
the number of calories in a cookie by the voltage across a resistor.

You could impose such a rule if you want, but it's not a standard part
of the general concept of unit conversions. There's no inherent reason
why such a product could not be meaningful - a quantity with those units
it might occur as one of the coefficients in the equation describing a
curve that has been fitted to data connecting the voltage applied to an
electric oven to the number of calories in the resulting cookies.
Suppose A arises as the result of multiplying Newtons by meters, and B arises
as a result of multiplying kilograms, meters and dividing by seconds squared.
You might want to be able to add these together.

Perhaps you meant "multiplying kilograms, meters squared and dividing by
seconds squared"? Otherwise, it doesn't work.

With that correction, A and B would have the same units, because of the
definition of Newtons as kg m/s^2. Addition of quantities with arbitrary
different set of units does not make sense. Adding A to B (after this
correction) could make sense, because the connection between Newtons,
kilograms, meters and seconds is NOT arbitrary.
 
Ð

МакÑим Фомин

On Mon, 17 Oct 2011 13:53:38 -0400, James Kuyper

Perhaps the poster is looking for something like Boost.Units. Although
obviously that's not applicable to C.

I don't need now such features, I just asked question about the issue
in C which confused me.
 
N

Nick Keighley

On Oct 18, 9:04 am, (e-mail address removed) (Gordon Burditt) wrote:

Back in physics class, there were something like 5 fundamental units
and all the others could be expressed in terms of them:

        distance, time, mass, electric charge, and temperature

This was referred to as the "MKS" system (meter, kilogram, second).
Actually, there were a lot of combinations of 5 "fundamental units"
you could use, the rule being that you're not allowed to have a
"fundamental unit" expressable in terms of other "fundamental units",
and you'd express the rest in terms of those 5.  If it has units
of distance/time**2, it's *NOT* a velocity and you shouldn't be
assigning it to a variable for velocity.  Checking this sort of
thing during exams can save you a lot of grief and bad exams scores.

One problem this brings up is that you need to support constants
with units, and the physics book wasn't always careful to put units
on its constants.  Formulas you find elsewhere are even less likely
to identify the units involved, but just state the units of all the
variables and the result.

Another problem is that you really need to handle unit-generic
routines, like printf() and strtod().  Quick, what's the printf
format for a floating point number in furlongs per fortnight?

I suppose some applications will demand that you add 'currency' as
a 6th fundamental unit.  Conversions between most units of the same
dimensionality, e.g. all distance units, are fixed.  That's not
true of currency.

which is why currency doesn't figure a lot in physics.
Then we were introduced to the "CGS" system (centimeter, gram,
second), which somehow managed to call the speed of light a
dimensionless constant of 1.  I never did like that.

I'm not surprised. The speed of light in cm/s certainly isn't 1!
Perhaps you meant http://en.wikipedia.org/wiki/Planck_units
 
J

James Kuyper

The last time I had to remind you of this was March 31st. Permission to
quote any part of any message I post, without proper attribution, is
denied. Your unjustified fear of being held responsible for falsely
attributing quoted text to someone using a spoofed user id doesn't
excuse you from your responsibility for properly attributing quotations.

There is not anything necessarily wrong with doing that multiplication,
but when you assign the result of it to a variable with incompatible
units, the compiler could raise an error.

That's why I listed assignment as one of the contexts where there is a
constraint requiring matching units (for those entering this discussion
late, I'm not talking about a C constraint; just a requirement for the
calculation to be meaningful).

....
One problem this brings up is that you need to support constants
with units, and the physics book wasn't always careful to put units
on its constants. Formulas you find elsewhere are even less likely
to identify the units involved, but just state the units of all the
variables and the result.

Two of the key things I learned in physics classes at Caltech were the
importance of associating both units and uncertainties with every
quantity. My real world experience has been that the actual scientists I
work with are extraordinarily lax about such things, which often causes
problems.

Two weeks ago I asked someone to determine whether there was any
evidence of a significant impact on the accuracy of our measurements
correlated with a particular event. Yesterday, I got a response that was
just a bunch of raw numbers, with no uncertainties, and not even a
qualitative assessment of their significance. I asked him, to at least
give me a statement about whether or not he thought it was significant.
His response was more numbers: comparable figures from last year, again
with no uncertainties and no verbal assessment of the significance of
the difference between last year's figure and this year's. I don't have
the authority to insist that he give me a more useful response, and I
have neither the data nor the time required to do that analysis myself.
I suspect he doesn't really understand what the term "statistically
significant" means. I had to tell our client "we don't know".
Another problem is that you really need to handle unit-generic
routines, like printf() and strtod(). Quick, what's the printf
format for a floating point number in furlongs per fortnight?

In a C-like system where types had units attached, printf("%f") would
need to be able to print any type whose promoted type is based upon
double, regardless of units. There would also be a need for some
mechanism for accessing a string representing the units - perhaps a
_unitsof operator, analogous to sizeof?
I suppose some applications will demand that you add 'currency' as
a 6th fundamental unit. ...

No, you need a different unit for each currency.

A unit-based system will be nearly useless unless arbitrary user-defined
units can be defined. Chemical calculations, for instance, often need to
distinguish between "moles of Carbon atoms" and "moles of Hydrogen
atoms". You'd better NOT cancel those out just because they're both
moles - you need to apply a context-specific conversion factor, such as
4 Hydrogen atoms/Carbon atom, for Methane, in order to get proper
cancellation.

In other contexts, units of "cookies" or "divisions" or "tables" might
be appropriate.

....
Then we were introduced to the "CGS" system (centimeter, gram,
second), which somehow managed to call the speed of light a
dimensionless constant of 1. I never did like that.

The CGS system does not make the speed of light 1. You're thinking of
Plank units. They're very convenient when you would otherwise find
yourself using equations with a lot of 'c's in them, but the absence of
units can make it easy to get lost in such calculations.
 
G

gwowen

The CGS system does not make the speed of light 1. You're thinking of
Plank units.

That's why carpenters are able to order materials using dimensionless
numbers like "2 lots of 4 by 2" and "3 lots of 6 by 4". They're using
Plank units.
 
J

James Kuyper

That's why carpenters are able to order materials using dimensionless
numbers like "2 lots of 4 by 2" and "3 lots of 6 by 4". They're using
Plank units.

How do they keep track of (and use) such small pieces? :)

Those numbers are not dimensionless, they just have units that are
implicit as a matter of custom.
 
P

Patrick Scheible

James Kuyper said:
No, you need a different unit for each currency.

Currencies are a mess. Not only are they not comparable from country to
country, but they are not comparable from time period to time period.
Even the way they are adjusted for inflation is a political process.
People with different agendas pick measures of inflation that emphasize
or deemphasize it. Making those choices, I think, is beyond the scope
of a programming language.

-- Patrick
 
B

BartC

James Kuyper said:
How do they keep track of (and use) such small pieces? :)

Those numbers are not dimensionless, they just have units that are
implicit as a matter of custom.

Like Knots.
 

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

Forum statistics

Threads
474,262
Messages
2,571,056
Members
48,769
Latest member
Clifft

Latest Threads

Top