size of a pointer on 4-bit system

S

Shao Miller

Ooh, heheh. I missed your point of the parentheses. My mistake. Don't
do that! :)

(For some reason I thought you were emphasizing the spacing differences
of '**' and '* *' and I didn't read the parentheses at all. :S )

But I don't quite understand what the latter's "intuitive" expectation
might be... That 'sizeof' would process everything until the closing
bracket because an opener came before it? If so, could the same
argument be made for:

*(x + 2)

versus:

(* x + 2)

? Is the problem that 'sizeof' requires some separation from its
operand, unlike '*'?
 
B

Ben Bacarisse

Tim Rentsch said:
BartC said:
Tim Rentsch said:
glen herrmannsfeldt <[email protected]> writes:
There's no reason a conforming implementation couldn't provide its
own four-bit data types, including arrays of such data types. The
rule that all non-bitfield types must be multiples of 'char' in
width applies only to Standard-defined types, not to types provided
as part of extensions.

OK, I agree. It does have the complication that

nybble *x;
x=malloc(100*sizeof(*x));

won't allocate 100 nybbles, unless sizeof works differently.
[snip]

The sizeof operator can be defined in a way that satisfies all
the Standard's requirements but still allows this example to
allocate only 100 nibbles.

So what would be the value of sizeof(*x)? It can only really
be 1 or 0. [snip elaboration]

Actually that isn't right. Using 'sizeof' on a non-standard
datatype may behave in unexpected ways. Here's a hint: sizeof
yields a result of type size_t; size_t is an (unsigned) integer
type; integer types larger than character types may have padding
bits. Can you fill in the rest?

I can't. Can the value of an operator that yields an integer have
padding bits? The wording is not always 100% unambiguous, but my
understanding that padding bits are part of the representation.

My first thought was that you want the padding bits (always supposing
they can be there in a value) to encode the fact the result is a
nibble size rather than a byte size, but I still can't square that with
the need for the result to be both "an integer" and "the size (in bytes)
of its operand".
 
K

Keith Thompson

Shao Miller said:
The 'sizeof' operator only requires parentheses when used with a
type-name. Your example clearly does not use a type-name, so it could
be: 100 * sizeof *x

true, but there's nothing wrong with writing 100*sizeof(*x).
 
S

Shao Miller

glen herrmannsfeldt said:

C requires char to be at least 8 bits, but it can be more. All
other types have to be multiples (including 1) of the size of
char.

That seems to prohibit a four bit type, which would be especially
useful on a four bit processor.

There's no reason a conforming implementation couldn't provide its
own four-bit data types, including arrays of such data types. The
rule that all non-bitfield types must be multiples of 'char' in
width applies only to Standard-defined types, not to types provided
as part of extensions.

You've made a common mistake here. You start with a statement
about something you think an implementation might benefit from
doing, and use that to draw a conclusion about what the Standard
allows. The reasoning process needs to go the other direction:
start with what the Standard allows (or more importantly in this
case, what it effectively prohibits), and show that a conforming
implementation could act as suggested and still not violate any
requirements. The reasoning given above proves nothing at all.

Interesting... So in this particular case, the Standard's definitions
that we might expect to apply to all object types needn't apply, because
these rules only apply to Standard-defined types. So actually, perhaps
we don't need to bother calling these subjects "types" at all, so as not
to confuse them with the usual Standard notions. In that case

appears to be agreeable. We could call them "extendo-types," just like
"nobjects," else-thread. Interesting...
 
R

Robert Miles

I'm so conditioned to C that I don't see the difference, but I can
imagine some language that has '**' as an exponent operator...?

Fortran does. I haven't checked if there are any more.
 
B

Bart van Ingen Schenau

even if the C languge say other
i think pointer is one unsigned number of fixed size

That might be what you think, but history does not agree with you.
The 80286 processor supports different sized pointers for data and
functions, and either of them could be larger than an int.
int == 16 bits
void* == 16 or 20 bits (effective size; depending on the memory model)
void(*)() == 16 or 20 bits (effective size; depending on the memory model)
There were different memory models for each combination of pointer sizes.
all that goes
different from above produce errors or wrong programming behaviours or
difficult code to understand

That has not been my experience. On the contrary, failing to understand
that pointers and integers are different, unrelated things is what causes
wrong programming habits and difficult to port code.

Bart v Ingen Schenau
 
G

glen herrmannsfeldt

Robert Wessel said:
On Sat, 2 Feb 2013 09:22:20 +0000 (UTC), Bart van Ingen Schenau
(snip)
While x86 far pointers are effectively about 20 bits long in real mode
(while the pointer was physically 32 bits in size), in 16-bit
protected mode, far pointers are closer to 30 bits in effective size.

I guess 29 is close to 30.

The segment selector has two bits of protection ring and the
global/local bit.

There is one 29 bit global address space, and a 29 bit space
for each task.

Starting with the 80386, the segment selectors work the same
way, but with a 32 bit offset, so 45 bits each. Would have been
more useful without a 32 bit MMU in between.

-- glen
 
G

glen herrmannsfeldt

Fortran does. I haven't checked if there are any more.

PL/I inherited it from Fortran, gawk (GNU awk) has it in
addition to the ^ operator.

Now, why doesn't C have one?

-- glen
 
B

BartC

glen herrmannsfeldt said:
PL/I inherited it from Fortran, gawk (GNU awk) has it in
addition to the ^ operator.

Now, why doesn't C have one?

Because all the best operator symbols have been used up; which symbol would
be used instead?
 
R

Rosario1903

Why do you believe that any representation other than an unsigned
integer would lead to errors, undesired program behaviour, or code
that's difficult to understand? What makes an unsigned integer
representation so special?

because i like unsigned numbers [i have good experience with unsigned]
 
J

James Kuyper

<Completely confused...>

There are two different grammar productions involving the sizeof
operator (6.5.3p1):

sizeof(type-name)
sizeof unary expression

Notice the absence of parentheses in the second case. Examples:

sizeof(long double complex)

sizeof !p->a[5].time

Note that if an expression does not qualify as unary, parentheses may be
needed to convert it into one: sizeof a + b is equivalent to (sizeof
a)+b; if what you want is sizeof(a+b), you'll have to explicitly insert
those parenthesis to force that interpretation. However, those
parentheses are quite different, syntactically, from the parentheses in
sizeof(long double).

This is a minor issue - parenthesizing the argument of a sizeof operator
is not always necessary, but it's generally not harmful, either.
In some unusual circumstances, worthy of the obfuscated C contest,
parentheses immediately following the sizeof keyword can fail to have
the effect you might have expected - sizeof(one)[two] is NOT parsed as
equivalent to (sizeof one)[two].
 
S

Shao Miller

[snip]

C requires char to be at least 8 bits, but it can be more. All
other types have to be multiples (including 1) of the size of
char.

That seems to prohibit a four bit type, which would be especially
useful on a four bit processor.

There's no reason a conforming implementation couldn't provide its
own four-bit data types, including arrays of such data types. The
rule that all non-bitfield types must be multiples of 'char' in
width applies only to Standard-defined types, not to types provided
as part of extensions.

You've made a common mistake here. You start with a statement
about something you think an implementation might benefit from
doing, and use that to draw a conclusion about what the Standard
allows. The reasoning process needs to go the other direction:
start with what the Standard allows (or more importantly in this
case, what it effectively prohibits), and show that a conforming
implementation could act as suggested and still not violate any
requirements. The reasoning given above proves nothing at all.

Interesting... So in this particular case, the Standard's definitions
that we might expect to apply to all object types needn't apply, because
these rules only apply to Standard-defined types. So actually, perhaps
we don't need to bother calling these subjects "types" at all, so as not
to confuse them with the usual Standard notions. In that case
That seems to prohibit a four bit type, which would be especially
useful on a four bit processor.

appears to be agreeable. We could call them "extendo-types," just like
"nobjects," else-thread. Interesting...

The Standard's definitions apply to all conforming programs, so to all
"object" type (both Standard-defined and user defined). What is doesn't
apply to are implementation defined types whose use requires what the
Standard defines as "Undefined Behavior", particularly the use of a
symbol in a manner reserved for the implementation.

It is forcing the program to invoke undefined behavior (which the
implementation has then defined) that lets the implementation "break"
the Standard's rules, since the Standard applies no rules in that case.

Why bother calling them "implementation defined types" if the subjects'
properties can deviate in dramatic ways from the usual, Standard-derived
expectations for types? Quite seriously, if these subjects are defined
only by the implementation and those definitions include references to
_some_ pieces of the Standard (including _some_ pieces about "types"),
doesn't it seem more natural to call these subjects by some other name
than to call them "types" at all? Using "implementation defined type"
implies that somehow it's a "type", but the implementation has stripped
some of what it means to be a "type"; this doesn't seem to be a
constructive approach, but a destructive one. (Where "constructive" is
not meant to be confused with "useful" or "enjoyable".)
 
G

glen herrmannsfeldt

(snip, someone wrote)
Off-topic, but: Do any of these care about '2 * * x' versus '2**x'?

You could make it in-topic by including a discussion about C operators.

I do remember a compiler that accepted the long obsolute =- operator,
and so one had to add space when assigning negative values.

x= -1;

In Fortran I, where ** originated (as far as I know) blanks were not
significant, even in keywords or variable names. That is still true in
fixed-form, but not in the free-form, optional since Fortran 90.

DO1I=1,10

DO 1 I = 1.10

are a DO statement and assignment statement, respectively.

PL/I has no reserved words, but requires space between adjacent keywords
and variables. There are some special exceptions. I believe like C,
both GOTO and GO TO are allowed in free-form Fortran and PL/I.

I don't know the others well enough to say.

-- glen
 
G

glen herrmannsfeldt

(snip on exponential operators)
Because all the best operator symbols have been used up;
which symbol would be used instead?

There must be come combinations of C characters that could be used.

Mostly, it is nice to have an operator for squaring, and other small
integer powers. Nothing wrong with pow() for the general case, but
how many compilers recognize

pow(x,2) or pow(i,2) (where i is int) as a squaring operation?

In Fortran and PL/I you can rely on the compiler to recognize **2 as
a square, and generate inline multiply instead of a procedure call.

-- glen
 
B

BartC

James Kuyper said:
There are two different grammar productions involving the sizeof
operator (6.5.3p1):

I was confused because I thought this was something to do with getting
sizeof to work with bitfields.
sizeof(type-name)
sizeof unary expression

I can never remember the rule. It's easier to just add the parentheses every
time.
 
G

glen herrmannsfeldt

(snip, someone wrote)
I can never remember the rule. It's easier to just add the
parentheses every time.

That, and the bitwise logical and shift operators which have
surprising precedence sometimes.

-- glen
 
K

Keith Thompson

Shao Miller said:
true, but there's nothing wrong with writing 100*sizeof(*x).

Please forgive me, but seeing and having to clarify upon tens of
requests for "which header do I need to #include for the sizeof
function?" and "how can the sizeof function take any kind of argument?"
and other such nonsense strikes me as a direct result of the near
ubiquity of this [unfortunate] pattern in professional C code. Of
course, having a book might also help these same knowledge-seekers.

Based on BartC's followup, I think he assumed that your post was
intended as a correction rather than as a clarification.
 
K

Keith Thompson

glen herrmannsfeldt said:
PL/I has no reserved words, but requires space between adjacent keywords
and variables. There are some special exceptions. I believe like C,
both GOTO and GO TO are allowed in free-form Fortran and PL/I.
[...]

Like C? C allows `goto`; `go to` is a syntax error.
 

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,077
Messages
2,570,567
Members
47,203
Latest member
EmmaSwank1

Latest Threads

Top