C vs. C++

K

Keith Thompson

CBFalconer said:
For example, imagine a system where, after writing 0 to ioport 5,
memory addresses 1000 to 2000 address memory on one chip. After
writing 1 to ioport 5, those addresses reach another chip. There
is NO way to define greater or smaller addresses between the
chips. Yet pointers have to be able to access both!

Suppose malloc() is able to allocate memory at address 1500. So I
call malloc(), store the resulting pointer value in a variable, and
store a value at that location:

int *ptr = malloc(sizeof *ptr);
/* assume this gives me addrss 1500 */
*ptr = 42;

After writing to ioport 5, I still need to be able
to dereference that pointer and get back the data I wrote:

/* ... */
printf("%d\n", *ptr); /* This has better print "42" */

Possible solutions, in a conforming implementation, are:

No code with defined behavior (i.e., behavior defined by the standard)
can yield an address in that range, so the behavior of those addresses
is irrelevant.

Writing to ioport 5 invokes undefined behavior, so once you've done
that, all bets are off.

The C implementation's pointer format includes the identity of the
appropriate memory chip. Before deferencing such a pointer, the
compiler must either prove that the appropriate chip is active, or
generate code to write to ioport 5 first.

In the first two cases, the fact that the pointers can't be ordered is
irrelevant; in the last case, the extra information can be used to
define a (perhaps arbitrary) total ordering.
So there can't be a portable method of ordering pointers. Maybe
C++ has some sort of provision that excludes such a mechanism. C
doesn't, to my knowledge.

No, there's no *portable* method of defining a total ordering on
pointer values. C doesn't require implementations to define or use a
non-portable method of doing so.

<OT>
C++, with its std::less, does impose such a requirement; the "<"
operator needn't impose a total ordering (which avoids imposing extra
work where it's not necessary), but std::less must do so. As for
offsetof, the implementation can use whatever non-portable tricks it
likes to implement this.
</OT>
 
K

Keith Thompson

Kaz Kylheku said:
You'd use new (std::nothrow) to avoid exceptions.

Ok, but you'd have to know about new (std::nothrow), and about any
other C++ features that are necessary to avoid exceptions. The C++
compiler, as far as I know, isn't going to help you enforce this.
 
J

James Kuyper

CBFalconer said:
For example, imagine a system where, after writing 0 to ioport 5,
memory addresses 1000 to 2000 address memory on one chip. After
writing 1 to ioport 5, those addresses reach another chip. There
is NO way to define greater or smaller addresses between the
chips. Yet pointers have to be able to access both!

A pointer must contain enough information to uniquely identify the
location that it points at. On such a system, the pointer would have to
contain enough information, directly or indirectly, for the system to
determine which chip it refers to. That information can be used to
determine an arbitrary ordering between pointers to data on the first
chip and data on the second chip. The obvious choice would be to order
all memory positions on the second chip higher than any memory position
on the first chip.
So there can't be a portable method of ordering pointers. Maybe
C++ has some sort of provision that excludes such a mechanism. C
doesn't, to my knowledge.

C++ mandates such ordering; how it is achieved is up to the implementor.
If there were no way around the problem you describe, then fully
conforming implementation of the C++ standard library for such a
platform would be impossible. This is a cost the C++ committee has
decided to accept; I strongly suspect that they did not expect the cost
to be significant.
 
N

Nate Eldredge

Phil Carmody said:
There is a way. In order to uniquely identify that memory location,
the '0' and '1' that are most recently written to the port are part
of the address. Otherwise 1234 in bank 0 and 1234 in bank 1 would
be compared equal, which they mustn't be.

But there's a distinction here between equality and relational testing.
If the two pointers are p and q, 6.5.9 (6) guarantees that `p != q' and
`!(p == q)'. But 6.5.8 (5) allows undefined behavior for any of the
comparisons `p < q', `p <= q', `p > q', or even the apparent tautology
`p <= q || p >= q'. They could give nonseniscal results or provoke
nasal demons.
 
K

Kaz Kylheku

Ok, but you'd have to know about new (std::nothrow), and about any
other C++ features that are necessary to avoid exceptions.

You mean you have to have a clue if you are to accomplish something
in a programming language?

That used to be taken for granted around here ten years ago.

Some C++ toolchains do offer support for turning off exception handling,
sicne this is actually not an uncommon requirement.
 
K

Kaz Kylheku

I'm hardly a C++ expert, but I think you can indeed encode promotion
rules. Here's a noddy example.

Very cool. Tested and works for me.

I combined our templates with my the main() function from my earlier example
(where max was a set of overloads), and it produced the same output.

Two thumbs up!

I have GNU C++ 4.3.2 available, but I tried it with just 3.4.3 and it's fine.

See, maybe Jacob's colleagues just need to get some smart external consultants.

There ought to be no need to revise hundreds of source files to switch
from a templated max to one based on overloaded functions (or even macros).
// promotion is symmetric
template<typename L, typename R>
struct promote { typedef typename promote<R, L>::ty ty; };

// promotion is reflexive
template<typename T>
struct promote<T, T> { typedef T ty; };

// prefer floating to integer (example)
template<>
struct promote<int, double> { typedef double ty; };

// many others... sorry, this bit is tedious.

It is, but we get to reuse the promote template anywhere we need
promotion. Very nice.

It would be nice if you could test ``this type is a subclass of that one''.
// now write a max which promotes properly
template<typename L, typename R>


... or computed from the parameters.

So there we have it. A max template where the two arguments can be different
types, and the return type is determined using promotion rules very similar to
those for built-in operator.

The whining can stop now, starting with me. :)
 
F

Flash Gordon

You mean you have to have a clue if you are to accomplish something
in a programming language?

What I want to know is why everyone is discussing C++ over here. Yes, it
started off as a comparison, but all that is currently being talked
about as far as I can see is C++. You all know where to find comp.lang.c++
 
K

Keith Thompson

Kaz Kylheku said:
You mean you have to have a clue if you are to accomplish something
in a programming language?

That used to be taken for granted around here ten years ago.

Some C++ toolchains do offer support for turning off exception handling,
sicne this is actually not an uncommon requirement.

What I actually meant was that if you want to write C code (which
includes having the compiler detect errors for your), a C++
compiler is not a particularly good tool for the job. What I
should have realized before posting was that introducing "new"
into the discussion, with or without (std::nothrow), takes the
discussion entirely outside the realm of C.
 
M

Mark Wooding

Kaz Kylheku said:
It would be nice if you could test ``this type is a subclass of that
one''.

This seems like it ought to be doable, with SFINAE and sufficient
deviousness. Alas, I'm insufficiently devious.

template<typename S, typename C>
struct subclassp {
struct yes { static char yn[2]; };
struct no { static char yn[1]; };
static yes *hack(C *c) { return 0; }
static no *hack(...) { return 0; }
static const bool yn = sizeof(hack((S *)0)->yn) > 1;
};

Now subclassp<X, Y>::yn is true if and only if X is a subclass of Y.
But turning this into a promote rule is beyond my meagre C++ skills, I'm
afraid.

-- [mdw]
 
P

Phil Carmody

Nate Eldredge said:
But there's a distinction here between equality and relational testing.
If the two pointers are p and q, 6.5.9 (6) guarantees that `p != q' and
`!(p == q)'. But 6.5.8 (5) allows undefined behavior for any of the
comparisons `p < q', `p <= q', `p > q', or even the apparent tautology
`p <= q || p >= q'. They could give nonseniscal results or provoke
nasal demons.

In what way does that contradict the fact that there is a way
to compare pointers, no matter what the platform and/or memory
architecture. C chosing to not oblige implementations to offer
such functionality doesn't contradict that.

Read what Chuck said, and what I said: "There is NO way to...",
and "There is a way". At no point do either of us say "within
the current C standards". Please learn to read. Chuck was trying
to make what C++ does appear to be impossible. As Keith and I
have both pointed out, that's nonsense.

Phil
 
N

Nate Eldredge

Phil Carmody said:
In what way does that contradict the fact that there is a way
to compare pointers, no matter what the platform and/or memory
architecture. C chosing to not oblige implementations to offer
such functionality doesn't contradict that.

Okay, insofar as a machine has a finite set of memory addresses, and any
finite set admits a total ordering, this is true.

My point was just that it's not hard to imagine machines where it is
considerably less convenient or efficient to compare (i.e. order)
pointers to different objects than to compare pointers to different
members of a single aggregate or array. So C++'s requirement, while
in theory possible to implement, may in practice be onerous.
Read what Chuck said, and what I said: "There is NO way to...",
and "There is a way". At no point do either of us say "within
the current C standards". Please learn to read. Chuck was trying
to make what C++ does appear to be impossible. As Keith and I
have both pointed out, that's nonsense.

I'm sorry that I misunderstood you, and I of course agree with your
clarified statement. I was misled by your phrase "compared equal",
which I read as referring (ambiguously) to C comparison operators. This
being comp.lang.c, people often do intend their statements to be
understood in the context of (standard) C, even when they don't say so.
 
K

Kaz Kylheku

Kaz Kylheku said:
It would be nice if you could test ``this type is a subclass of that
one''.

This seems like it ought to be doable, with SFINAE and sufficient
deviousness. Alas, I'm insufficiently devious.

template<typename S, typename C>
struct subclassp {
struct yes { static char yn[2]; };
struct no { static char yn[1]; };
static yes *hack(C *c) { return 0; }
static no *hack(...) { return 0; }
static const bool yn = sizeof(hack((S *)0)->yn) > 1;
};

Now subclassp<X, Y>::yn is true if and only if X is a subclass of Y.
But turning this into a promote rule is beyond my meagre C++ skills, I'm
afraid.

Actually, that's okay because promote rules shouldn't follow the hierarchy
anyway. They are based on other considerations, like preserving precision and
semantics of exactness, and should be hand-crafted. Thanks.
 
C

Chris H

In message
There is /nothing/ that can be achieved more elegantly or more
efficiently in C, than it can be achieved in C++. Nothing. If you
think there's something then I'll listen intently.

Ignore Tomas he has VERY little experience and very strong opinions
 
R

Richard

Chris H said:
In message


Ignore Tomas he has VERY little experience and very strong opinions

Chris, can you give me an example of something you can do in the C
Language that can not be done "as easily" or efficiently in the C++
language. I stress the "language" not an implementation of it where, for
example, only a C compiler works for some processor/board you might know
of. I keep asking, but still have not received any examples.
 
K

Kaz Kylheku

In message


Not according to Bjarne Stroustrup.

Also according to Stroustrup:

``I have never seen a program that could be expressed better in C than
C++ (and I don't think such a program could exist -- every C
construct has an obvious C++ equivalent).'' -- Stroustrup

``Every C program can be written in essentially the same way in C++,
with the same run-time and space efficiency.'' -- Stroustrup
 
C

Chris H

Kaz Kylheku said:
Also according to Stroustrup:

Yes according to Stoustrup

the two comments below do NOT say C++ is a superset of C. Read them
carefully. He says anything you can write in C he things you can write
better in C++. It does NOT say one is a superset of the other
``I have never seen a program that could be expressed better in C than
C++ (and I don't think such a program could exist -- every C
construct has an obvious C++ equivalent).'' -- Stroustrup

``Every C program can be written in essentially the same way in C++,
with the same run-time and space efficiency.'' -- Stroustrup


And from his own web site
http://www.research.att.com/~bs/bs_faq.html#C-is-subset

Is C a subset of C++?
In the strict mathematical sense, C isn't a subset of C++. There are
programs that are valid C but not valid C++ and even a few ways of
writing code that has a different meaning in C and C++.


What do you think of C/C++?
No that's not really a question I often get. In that sense, it is the
only "fake FAQ" in this FAQ. However, it ought to be a FAQ because
people use "C/C++" as if it meant something specific and as if they knew
what it meant, leading to much confusion and misery. People should ask
"What is C/C++?" and then on reflection stop using the term. It does
harm.
There is no language called "C/C++". The phrase is usually used by
people who don't have a clue about programming (e.g. HR personnel and
poor managers). Alternatively, it's used by people who simple do not
know C++ (and often not C either). When used by programmers, it
typically indicates a "C++ is C with a few useful and a lot of useless
complicated features added" attitude. Often, that is the point of view
of people who like to write their own strings and hash tables with
little knowledge of the standard library beyond printf and memcpy. There
are people who stick to a restricted subset of C++ for perfectly good
reasons, but they (as far as I have noticed) are not the people who say
"C/C++".

I use C/C++ only in phrases such as "C/C++ compatibility" and "C/C++
community".
 
J

jacob navia

Ian said:
Fair enough, but what's your "something"?

max(a,b)
min(a,b)

As pointed out elsethread, this needs a special template
and generic functions in C++. Imagine.

In C a simple macro is enough.
 
R

Richard

Kaz Kylheku said:
Also according to Stroustrup:

``I have never seen a program that could be expressed better in C than
C++ (and I don't think such a program could exist -- every C
construct has an obvious C++ equivalent).'' -- Stroustrup

``Every C program can be written in essentially the same way in C++,
with the same run-time and space efficiency.'' -- Stroustrup

Which makes me realise why I STILL have not received an answer to my
question ...
 

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
474,432
Messages
2,571,681
Members
48,796
Latest member
Greg L.

Latest Threads

Top