By the same argument,
requires an extension in some sense, because it is probably accomplished
using assembly.
No, it doesn't require an extension, because it can be interpreted by a
compiler accepting exactly the language as defined by the C standard.
The compiler can use any magic it likes to accomplish anything by any
manner. That's not an extension, as long as it is part of the language.
The definition of offsetof is required to become part of the language
accepted by the implementation, I believe.
It is highly likely that your compilers memcpy() is implemented in
assembly and not in C, because it may behave more efficiently given
certain conditions like alignments or object sizes. There's nothing
wrong with that and it is not an extension.
That depends on how memcpy is defined.
string.h:
// ...
void *memcpy(void *restrict, const void *restrict, size_t);
// ...
string.asm:
_memcpy:
# inefficient assembly implementation
jmp _memmove
In this case, no extension is required, since the assembly version of
memcpy is not read at all by the compiler.
[...]
Let's make a simple definition that everyone can agree on:
If it compiles on every ideal, conforming C compiler then it requires
only the C language.
If it fails to compile on any conforming C compiler then it requires an
extension.
Sure, this means
#include <stddef.h>
struct S {
int m;};
enum {
zero = offsetof(struct S, m)
};
does not make use of an extension. I can agree on that. But how is
offsetof defined? Let's say it is defined in <stddef.h> as
typedef char __char;
#define offsetof(s, m) ((__char *) &((s *) 0)->m - (__char *) (s *) 0)
Now, after expanding offsetof, it no longer compiles on every ideal,
conforming C compiler. In fact, it violates a constraint which would
cause at least one implementation to reject the program with a hard
error. So by your definition, this _implementation of_ offsetof does make
use of an extension, unless I'm misunderstanding your message.- Hide quoted text -
- Show quoted text -
If you expand your macro, so that the code does this, then you have
indeed violated the C language because that is very likely to fail.
#define offsetof(s, m) ((__char *) &((s *) 0)->m - (__char *) (s *) 0)
On the other hand, if you simply use the offsetof() macro and trust
your implementation to implement it as it should then there is no
violation of the standard (indeed, if you do it any other way then you
'have a screw loose').
Similarly,
i++;
may actually be implemented as:
_asm INC EAX;
which is not part of the C language, but why should I care? I am
responsible to write compliant code and the compiler is responsible to
translate it into machine instructions. Besides asking how does
offsetof() work, we may as well ask how malloc() works etc. Chances
are good that a large percentage of the actual internals of a compiler
require assembly language trickery. But any of that is neither here
nor there and is simply covered in the implementation details.
Whether they use assembly or library calls or a giant pile of
interpreted Lisp in the background isn't all that important. They can
accomplish the goal any way that they like, as long as it does what is
promised. I think that your major point is "A C compiler cannot be
accomplished strictly using C, because an extension is going to be
needed somewhere along the way." I don't think that anyone disagrees
with that (or if they do, the disagreement is not important). What is
important is that they accomplish the goals with whatever means are at
their disposal and that if I perform my part of the bargain (writing
correct C code) then they must also accomplish their part of the
bargain (correctly translating the C code as required by the
standard).
A conforming program should compile on any C compiler that claims to
conform. If it does not compile and the vendor claims to have a C
compiler then I have the right to complain and ask that the defect be
fixed. If the defect is not fixed in a timely manner then I have a
right to ask for my money back.