Microsoft abandons the C language

J

James Kuyper

On 29-Aug-12 03:54, Jens Gustedt wrote: ....

I think you (or perhaps your compiler) have this backwards.

"extern inline" (or just "inline", since "extern" is default for
functions) will create a function body with external linkage _and_ tell
the compiler to inline calls. So, if you use this in a header file that
is included in ten different source files, you will end up with TEN
function bodies with external linkage.

No, it does not create an external definition. The 'extern' keyword
asserts that there is an external definition, giving the compiler
permission to try to call it, but the external definition itself must be
provided separately. Where that function definition is provided, at
least one declaration of that function in the same translation unit must
omit both the 'extern' and 'inline' keywords - otherwise, it would
provide an 'inline definition' (6.7.4p7), and would therefore NOT
provide an external definition (6.9p5). The most reasonable thing is for
the declaration with this characteristic be the one that occurs at the
start of the external definition, but that's not actually required by
the standard (which seems a little odd to me).
AIUI, explicit inline directives are not an "optimization"; if your
compiler ignores them, it is not conforming.

The main defining characteristic of 'inline' keyword is that it "...
suggests that calls to the function be as fast as possible." That sounds
like a request for optimization to me. Whether or not it is an actual
optimization depends upon whether or not the compiler chooses to take
that suggestion into consideration.
It is only an "optimization" for the compiler to inline calls (and
possibly remove function bodies) when there are NOT any "inline" directives.

'inline' is a keyword, not a directive. The standard uses the word
"directive" only in the context of pre-processing.
It's an optimization, whether or not there's an 'inline' keyword,
because the compiler always has the option of either inlining a function
call, or not inlining it - the 'inline' keyword doesn't change that,
it's no more than a suggestion.
"static" suppresses the generation of (potentially redundant) function
bodies that will never be called.

No, an implementation is still free to create a separate function
bodies, whether or not they ever get called.
If your compiler ignores valid "inline" directives, then it becomes
necessary for ONE of the function definitions to be "extern", so that a
function body is generated, but the rest should be "static".

No, if it decides to ignore the 'inline' keyword, the function body it
creates must have internal linkage, not external. It does not satisfy
the requirement (that might exist due to some other translation unit in
the same program) for a function with that name and external linkage.
 
L

Les Cargill

Jens said:
Am 29.08.2012 14:57, schrieb Les Cargill:
Jens said:
Am 29.08.2012 10:01, schrieb David Brown:
On 29/08/2012 02:15, Keith Thompson wrote:
[...]
Yes, that works because it specifies external linkage for `foo()'.
I think that "static inline" was what he meant to write originally.
Thank you Jens.

It's not what I meant to write, but it's certainly what I should
have meant to write. I'm not as familiar with how C handles inline
functions as I should be.


Usually when you have an "inline" function, you do not want external
linkage. As with all functions that you don't explicitly want exported
from the compile unit, you should add "static". It is very rare to see
an "inline" function that should not have been declared "static inline".

Hm, I use inline functions a lot and my mileage seems to be completely
different from yours.

I have small to medium sized functions in headers as inline, and I
don't want them to be repeated in every compilation unit, so I don't
have them static.

The inline directive specifically asks that the thing be repeated for
every ... call to them. That's more or less the definition of it -
"treat this as if is were a '#define...' macro using different syntax."

That's not *exactly* right, but it's a good first approximation.

No that is not how C99 and C11 see it. C11 says for the intention behind
inline:

Making a function an inline function suggests that calls to the
function be as fast as possible. The extent to which such
suggestions are effective is implementation-defined.

I makes not much suggestions of how this goal should be achieved,
either.
I see that the opposite way -

it is not completely clear to me what you mean by oposite, here
the instantiation(s) and visibility of an identifier are mostly
disjoint properties.

sure, but what is the connection?

"inline" affects how things are instantiated. "static" changes
the visibility. Those are mostly disjoint properties. The Venn
diagram probably has some overlap.
Fact is that the inline keyword added to a static function doesn't
force anything and doesn't change the observable behavior of the
program.

It does ( possibly ) change the behavior of the compiler. If
you had certain optimizations on, the compiler might inline it anyway,
and in that case, it wouldn't change the behavior of the compiler.


I'd say we care about the behavior of the compiler as well as the
behavior of the program - we want to be SEI Level 2 at least,
and that means you know things about the validity of the operation of
the toolchain.
Replacing static by inline changes the observable behavior.

Adding inline to the definition of an extern function that is placed
in a header file can change a non-conforming program into a conforming
one.

That doesn't make any sense to me :) If it's extern, it's extern
and can't really be inline. I just have no exposure to doing
that.
 
S

s0suk3

He was talking about reimplementing his compiler so that it ran as a metro app (which is pretty crazy to even think about, and as he's been told, hedoesn't need to do that; the desktop still exists in Windows 8). He wasn'ttalking about using COM in general.

I forgot to mention, VS 2012 introduces a new set of extensions called C++/CX for COM development. This is what jacob was referring to as "managed C++", although it's actually not managed C++, it just looks like it (they usedmuch of the same syntax as for C++/CLI). With C++/CX, the equivalent HelloCom example would apparently be as easy as:

ref class HelloCom
{
void SayHello()
{
// Probably can't use MessageBox here, but some WinRT class
}
};

Although I think C++/CX only works for Metro apps, not desktop apps.
 
J

Jens Gustedt

Am 29.08.2012 19:32, schrieb Les Cargill:
Jens Gustedt wrote:

That doesn't make any sense to me :) If it's extern, it's extern
and can't really be inline. I just have no exposure to doing
that.

So just to expose you to that a bit, here is an example taken directly
from the C standard

inline double fahr(double t) {
return (9.0 * t) / 5.0 + 32.0;
}

<snip>

extern double fahr(double); // creates an external definition

Jens
 
K

Keith Thompson

Jens Gustedt said:
Hm, I use inline functions a lot and my mileage seems to be completely
different from yours.

I have small to medium sized functions in headers as inline, and I
don't want them to be repeated in every compilation unit, so I don't
have them static.

I use the "instantiation" syntax of C99 to force the generation of the
symbol in exactly one .c file.
[...]

What is this "instantiation" syntax? Can you show an example? (The
word doesn't appear in the standard.)
 
J

James Kuyper

On 08/29/2012 02:28 PM, Jens Gustedt wrote:
....

[citing 6.7.4p10, which is a non-normative example]
... A file scope declaration with extern creates an external definition. ....
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Is the non-normative text of 6.7.4p10 incorrect, or my understanding of
C? Possibly, both?
 
J

James Kuyper

I use the "instantiation" syntax of C99 to force the generation of the
symbol in exactly one .c file.
[...]

What is this "instantiation" syntax? Can you show an example? (The
word doesn't appear in the standard.)

I think he's referring to EXAMPLE 1 in 6.7.4p10; I've just posted a
message arguing that the example is in error.
 
V

Vincenzo Mercuri

Il 29/08/2012 20:51, James Kuyper ha scritto:
On 08/29/2012 02:28 PM, Jens Gustedt wrote:
...

[citing 6.7.4p10, which is a non-normative example]
... A file scope declaration with extern creates an external definition. ...
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Is the non-normative text of 6.7.4p10 incorrect, or my understanding of
C? Possibly, both?

In my understanding, a declaration with "extern" makes the function
definition with "inline", in the same translation unit, an external
definition. That's what "creates an external definition" stands for,
in my opinion.
 
N

Nick Bowler

On 08/29/2012 02:28 PM, Jens Gustedt wrote:
...

[citing 6.7.4p10, which is a non-normative example]
... A file scope declaration with extern creates an external definition. ...
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Since "extern double fahr(double);" is a declaration of fahr without the
inline specifier at file scope, then the text in 6.7.4p7 regarding inline
definitions no longer applies. In the example, this declaration directly
causes the earlier definition of fahr to become an external definition, as
opposed to an inline definition.

Given this, I don't think it's unreasonable to say for this example
that it is in fact the second declaration of fahr which creates the
external definition.
 
V

Vincenzo Mercuri

Il 29/08/2012 21:27, Nick Bowler ha scritto:
Since "extern double fahr(double);" is a declaration of fahr without the
inline specifier at file scope, then the text in 6.7.4p7 regarding inline
definitions no longer applies. In the example, this declaration directly
causes the earlier definition of fahr to become an external definition, as
opposed to an inline definition.

Given this, I don't think it's unreasonable to say for this example
that it is in fact the second declaration of fahr which creates the
external definition.

Exactly what I meant, but my english is not as good : )
 
J

James Kuyper

Il 29/08/2012 20:51, James Kuyper ha scritto:
On 08/29/2012 02:28 PM, Jens Gustedt wrote:
...

[citing 6.7.4p10, which is a non-normative example]
... A file scope declaration with extern creates an external definition. ...
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Is the non-normative text of 6.7.4p10 incorrect, or my understanding of
C? Possibly, both?

In my understanding, a declaration with "extern" makes the function
definition with "inline", in the same translation unit, an external
definition. That's what "creates an external definition" stands for,
in my opinion.

Yes, but as far as I know, there's nothing in the normative text that
says any such thing. It's only the non-normative text of this example
which gives any reason to expect such semantics. If I'm right about
that, then the example is in error. If I'm wrong about that, I'd
appreciate a citation of the relevant normative text. Unless it is
worded in such a way as to override either 6.9p5 or 6.9.1p1, the
existence of such normative text would constitute a defect in the standard.

That's one of the key distinctions between normative and non-normative
text: if non-normative text is in conflict with normative text, the
non-normative text is simply wrong. The non-normative text might
describe the committee's intent, but it will still be wrong, and the
normative text will still be correct, unless and until the committee
issues a resolution to the defect report that says otherwise.

If two different pieces of normative text are in conflict, the standard
is defective, and there will be no meaningful answer to the question of
which piece is correct, until the committee issues a resolution to the
defect report.
 
J

James Kuyper

On 08/29/2012 02:28 PM, Jens Gustedt wrote:
...

[citing 6.7.4p10, which is a non-normative example]
... A file scope declaration with extern creates an external definition. ...
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Since "extern double fahr(double);" is a declaration of fahr without the
inline specifier at file scope, then the text in 6.7.4p7 regarding inline
definitions no longer applies. In the example, this declaration directly
causes the earlier definition of fahr to become an external definition, as
opposed to an inline definition.

OK - that makes sense. However, as I read 6.7.4p7, it would also have
the same effect without the 'extern' keyword. The example would have
been less confusing with out it.
Given this, I don't think it's unreasonable to say for this example
that it is in fact the second declaration of fahr which creates the
external definition.

I disagree, there. It's the previous definition that creates the
definition. The second declaration merely determines whether the
definition, which has already been created, is an inline definition or
and external definition.
 
V

Vincenzo Mercuri

Il 29/08/2012 21:32, James Kuyper ha scritto:
Il 29/08/2012 20:51, James Kuyper ha scritto:
On 08/29/2012 02:28 PM, Jens Gustedt wrote:
...

[citing 6.7.4p10, which is a non-normative example]

... A file scope declaration with extern creates an external definition.
...
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Is the non-normative text of 6.7.4p10 incorrect, or my understanding of
C? Possibly, both?

In my understanding, a declaration with "extern" makes the function
definition with "inline", in the same translation unit, an external
definition. That's what "creates an external definition" stands for,
in my opinion.

Yes, but as far as I know, there's nothing in the normative text that
says any such thing. It's only the non-normative text of this example
which gives any reason to expect such semantics. If I'm right about
that, then the example is in error. If I'm wrong about that, I'd
appreciate a citation of the relevant normative text. Unless it is
worded in such a way as to override either 6.9p5 or 6.9.1p1, the
existence of such normative text would constitute a defect in the standard.
[...]

I think a relevant part of the Standard is the following:

N1570 6.7.4p7:

[...] If all of the file scope declarations for a function in a translation
unit include the inline function specifier without extern, then the
definition in that translation unit is an inline definition. [...]

In my opinion this implies that if there is at least one file scope
declaration for the same function with "extern" then that definition is
an "external definition" as opposed to "inline definition".
 
R

rashid

To my untrained eyes, that looks like correct C11. Maybe even C99,
but there are some features that I've never used, so I cannot say for
sure.

Look, what it is this languages of C11 and C99 what everyone talks about?
I never heard of them. C++, sure of course I know. C11 or C22 or Cff...
hocus pocus!

I am talking about the C language which MSVC++ will compile correctly,
and just as portable to Unix or Apple.
You probably use an extension language with all this strange stuff. For
example, in C you cannot have vla[size] where size is a variable. You
must do #define size 20 instead.

VLA's have been part of C since C99. Have you been living under a
rock for the past 13 years?

OK, so this is in "C99". I am talking here about C, not any extension
language.
I'll get the popcorn going, while I wait to see what Nemesis have
prepared for you.

WTF??
 
N

Nick Bowler

On 08/29/2012 02:28 PM, Jens Gustedt wrote:
...

[citing 6.7.4p10, which is a non-normative example]

... A file scope declaration with extern creates an external definition.
...
extern double fahr(double); // creates an external definition

That comment is inconsistent with my understanding of the normative text
of the standard. In particular, 6.9p5 requires that an external
definition define be the definition of either a function or an object.
It's clearly not an external definition of an object, and the grammar
for a function definition in 6.9.1p1 requires a compound-statement which
is missing from that statement.

My understanding is that, in conflict with 6.7.4p10, a file scope
declaration with extern, but no corresponding compound statement
defining the body of the function, is not a definition, and in
particular, is not an external definition, nor does it somehow cause
such a definition to be created.

Since "extern double fahr(double);" is a declaration of fahr without the
inline specifier at file scope, then the text in 6.7.4p7 regarding inline
definitions no longer applies. In the example, this declaration directly
causes the earlier definition of fahr to become an external definition, as
opposed to an inline definition.

OK - that makes sense. However, as I read 6.7.4p7, it would also have
the same effect without the 'extern' keyword. The example would have
been less confusing with out it.

You are correct that the extern specifier is not required. All of the
following should be equivalent for the purposes of that example:

double fahr(double);
extern double fahr(double);
extern inline double fahr(double);

and all the umpteen minor variations thereof. I don't think any of
these are more or less clear than the others, because the same sentence
in 6.7.4p7 applies to all three declarations in exactly the same way.
I disagree, there. It's the previous definition that creates the
definition.

It is a function definition, yes, but not necessarily an external
definition (which are the words used in the comment).
The second declaration merely determines whether the definition, which
has already been created, is an inline definition or and external
definition.

If we delete the second declaration of fahr from the example, the
external definition goes away. I think "create" is a reasonable
word to use, especially given that this is non-normative text. The
following definition of "create" from my dictionary seems to directly
apply to this situation

create
v 1: make or cause to be or to become; "make a mess in one's
office"; "create a furor" [syn: {make}]

as it is the second declaration which causes the earlier function
definition to become an external definition.
 
J

James Kuyper

Look, what it is this languages of C11 and C99 what everyone talks about?
I never heard of them. C++, sure of course I know. C11 or C22 or Cff...
hocus pocus!

Your lack of awareness of these international standards doesn't make
people who are aware of them liars. It just makes you ignorant.
Unusually so - virtually anyone paying any attention to C should have
heard of C99 many times in the past decade.
I am talking about the C language which MSVC++ will compile correctly,
and just as portable to Unix or Apple.

MSVC++ doesn't own that language. ISO does - and ISO doesn't match your
prejudices about what constitutes C. ISO C90 is widely portable; I'm not
sure what differences there might be between ISO C90 and the language
that MSVC++ compiles when it comes closest to being fully conforming to
C90. However, if there are any such differences, I can guarantee you
that the ISO C90 side of the difference is more widely portable than the
MSVC++ side.

Fully conforming implementation of C99 are still rare, but code that
uses most of the new C99 features can be compiled on every platform you
mention - but not by MSVC++. Implementation of C2011 has just barely
begun, but it will probably eventually be implemented on all of those
same platforms - but almost certainly not by MSVC++.

.....
OK, so this is in "C99". I am talking here about C, not any extension
language.

C now officially means C99. That's what ISO says, and ISO has the right
to say so. It's not an extension; the language you refer to is now an
officially obsolete version of C (twice over).

He's correctly identifying you as someone suffering from a bad case of
hubris <http://en.wikipedia.org/wiki/Nemesis_(mythology)>.
 
B

Ben Bacarisse

rashid said:
Look, what it is this languages of C11 and C99 what everyone talks about?
I never heard of them. C++, sure of course I know. C11 or C22 or Cff...
hocus pocus!

There's a need to distinguish between the various versions of the C
standard. That's all the numbers mean. The language "C" -- unadorned
with any numbers -- is, as of a short while ago, defined by a standard
that no compiler yet supports. In practice, all people now program in a
language that is not C as currently defined by ISO.

But there are lots of "not C as currently defined by ISO" languages.
I am talking about the C language which MSVC++ will compile correctly,
and just as portable to Unix or Apple.

MS stopped supporting the revisions to the C standard (at least the ones
that are not shared with C++) some time ago. The language which MSVC
will compile correctly is often called C90 or ANSI C, but MSVC include
extensions by default, so in effect the language you are talking about
is "C90 plus some other bits".
You probably use an extension language with all this strange stuff. For
example, in C you cannot have vla[size] where size is a variable. You
must do #define size 20 instead.

VLA's have been part of C since C99. Have you been living under a
rock for the past 13 years?

OK, so this is in "C99". I am talking here about C, not any extension
language.

Without any clarification, "C" is ambiguous. You may know what you
mean by C, but in a group where people use lots of different systems and
who need to refer to a language in the process of changing, the numbers
are a great help.

<snip>
 
J

Jens Gustedt

Am 29.08.2012 21:47, schrieb Vincenzo Mercuri:
I think a relevant part of the Standard is the following:

N1570 6.7.4p7:

[...] If all of the file scope declarations for a function in a translation
unit include the inline function specifier without extern, then the
definition in that translation unit is an inline definition. [...]

In my opinion this implies that if there is at least one file scope
declaration for the same function with "extern" then that definition is
an "external definition" as opposed to "inline definition".

yes, basically

this implies that there are three possible idioms for instantiation of
inline functions. If you have a header file with something like

inline void f(void) { }

Then any of the following three in a .c file that includes the header
will make this definition an external definition for the compilation
unit.

extern inline void f(void); // includes extern and inline

extern void f(void); // doesn't have inline

void f(void); // doesn't have inline

This is what I meant with "instantiation" syntax. (yes, the term is
not used in the standard, but conceptually it comes pretty close to
it.)

And this is how it basically works with modern gcc.

Jens
 
J

Jens Gustedt

Am 29.08.2012 22:07, schrieb Nick Bowler:
If we delete the second declaration of fahr from the example, the
external definition goes away. I think "create" is a reasonable
word to use, especially given that this is non-normative text. The
following definition of "create" from my dictionary seems to directly
apply to this situation

create
v 1: make or cause to be or to become; "make a mess in one's
office"; "create a furor" [syn: {make}]

as it is the second declaration which causes the earlier function
definition to become an external definition.

This is why I would all the second declaration (in any of its three
variants) an "instantiation" of the function, I think this is what some
related programming language that once invented the concept of "inline"
calls this.

Jens
 
J

Jens Gustedt

Am 29.08.2012 22:36, schrieb James Kuyper:
Fully conforming implementation of C99 are still rare, but code that
uses most of the new C99 features can be compiled on every platform you
mention - but not by MSVC++. Implementation of C2011 has just barely
begun,

no actually, it is already quite advanced. I think clang already
implements most of the language features (those that impose extensions
of the syntax) and part of the library is also already there.
but it will probably eventually be implemented on all of those
same platforms - but almost certainly not by MSVC++.
C now officially means C99. That's what ISO says, and ISO has the right
to say so.

Sorry to correct you :) but no, officially C now means C11. C11
declared C99 obsolete.

Jens
 

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,079
Messages
2,570,575
Members
47,207
Latest member
HelenaCani

Latest Threads

Top