Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

derived-type object

8 views
Skip to first unread message

Phred Phungus

unread,
Feb 14, 2010, 1:27:05 AM2/14/10
to
Is there such a thing as a derived-type object in C? (I believe there is.)

If so, can someone show me a bit of referent source?

Dankenstein,
--
fred

Kaz Kylheku

unread,
Feb 14, 2010, 1:37:11 AM2/14/10
to
On 2010-02-14, Phred Phungus <Ph...@example.invalid> wrote:
> Is there such a thing as a derived-type object in C? (I believe there is.)

If you already believe, why do you need facts?

Phred Phungus

unread,
Feb 14, 2010, 2:09:35 AM2/14/10
to

Because, ten years ago, I believed that my country would not initiate 2
asian land wars.

I was fireproofing an office building on 9/11, believing that someone
was minding the switch.

But then I have extraordinary beliefs about what we can do here in ABQ.
Indeed, I think we need derived-type objects. I rub elbows with all
these education types. I doubt that they have ever been enjoined to
embrace something abstract.
--
fred

Barry Schwarz

unread,
Feb 14, 2010, 2:50:55 AM2/14/10
to
On Sat, 13 Feb 2010 23:27:05 -0700, Phred Phungus
<Ph...@example.invalid> wrote:

>Is there such a thing as a derived-type object in C? (I believe there is.)
>
>If so, can someone show me a bit of referent source?

Wouldn't it have been easier just to scan any one of the many free
drafts of the standard. See 6.2.5.

--
Remove del for email

Eric Sosman

unread,
Feb 14, 2010, 8:57:08 AM2/14/10
to
On 2/14/2010 1:27 AM, Phred Phungus wrote:
> Is there such a thing as a derived-type object in C? (I believe there is.)

If by "derived-type object" you mean "an object of a type
not built into C, but derived from C's built-in types," then
the answer is "Maybe." It is certainly possible to derive new
types (by making arrays or structs or unions of existing types,
or by forming pointer types for them), and all that remains is
to run a program that uses an object of such a type.

(There are also function types, all of which are derived
types, but no way to create "objects" of those types.)

> If so, can someone show me a bit of referent source?

For my guess at the meaning of "derived-type object,"
ISO/IEC 9899:1999(E), Section 6.2.5, paragraph 20. If that's
not the meaning you have in mind, please explain in more detail.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Nick Keighley

unread,
Feb 15, 2010, 5:16:53 AM2/15/10
to
On 14 Feb, 06:27, Phred Phungus <Ph...@example.invalid> wrote:

> Is there such a thing as a derived-type object in C?  (I believe there is.)
>
> If so, can someone show me a bit of referent source?

what's a "derived-type object"? C doesn't have "objects" in the C++
sense. If by "derived-type" you mean inheritance then C doesn't have
that either.

Richard Heathfield

unread,
Feb 15, 2010, 9:48:50 AM2/15/10
to
Nick Keighley wrote:
<snip>

> [...] C doesn't have "objects" in the C++
> sense.

Yes, it does. C++'s definition of "object" is pretty much the same as
C's definition.

Or, if you prefer:

You're right, it doesn't - and neither does C++.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999
Sig line vacant - apply within

Phred Phungus

unread,
Feb 15, 2010, 8:40:44 PM2/15/10
to
Richard Heathfield wrote:
> Nick Keighley wrote:
> <snip>
>
>> [...] C doesn't have "objects" in the C++
>> sense.
>
> Yes, it does. C++'s definition of "object" is pretty much the same as
> C's definition.
>
> Or, if you prefer:
>
> You're right, it doesn't - and neither does C++.
>
> <snip>
>


Thanks all for responses. 6.2.5.20 has reassured me of my better
recollection.

In reading up on singly-linked lists, it became apparent that I might
better work up doubly-linked lists. Again I turned to the source in
unleashed, that has a DLLIST library that is consistent with the
terminology from SLLIST.

In compiling the drivers, I stumbled on a couple things:

$ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out
dl2.c: In function �main�:
dl2.c:170: warning: missing braces around initializer
dl2.c:170: warning: (near initialization for �ThisCity.Nation�)
dl2.c:170: warning: missing initializer
dl2.c:170: warning: (near initialization for �ThisCity.CityName�)

DLLIST *List = NULL;
DLLIST *Safe = NULL;
CITY *City = NULL;
CITY ThisCity = {0};
CITY *TempCity = NULL;
CITY *First;
CITY *Second;

Line 17o is the one with curly braces. Why did I need to add the -lm
when math.h was already included?

The other driver was dllistmn.c:

$ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl1.c -o out
dl1.c:44: warning: unused parameter �Args�
dl1.c: In function �main�:
dl1.c:129: warning: missing braces around initializer
dl1.c:129: warning: (near initialization for �Email.Name�)
dl1.c:129: warning: missing initializer
dl1.c:129: warning: (near initialization for �Email.Address�)
dl1.c:130: warning: unused variable �e�
$

EMAIL Email = {0};
EMAIL *e = NULL;

I don't see where this app finds any e-mails. Maybe Dann knows.
--
fred

Richard Heathfield

unread,
Feb 16, 2010, 1:31:40 AM2/16/10
to
Phred Phungus wrote:
<snip>

> In compiling the drivers, I stumbled on a couple things:
>
> $ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out
> dl2.c: In function �main�:
> dl2.c:170: warning: missing braces around initializer

gcc is warning you about a non-problem. The = {0} idiom is perfectly good C.

> Why did I need to add the -lm
> when math.h was already included?

There's no particular reason why adding a header should automatically
link in its corresponding library (other than good sense, of course!);
the GNU folk seem to think it makes sense to drive people nuts with
stupid linker error messages, and no doubt they are, in some way,
correct, although I can't for the life of me think in what way that
might be.

Ersek, Laszlo

unread,
Feb 16, 2010, 2:43:53 AM2/16/10
to
In article <zqGdnZnn14NXpufW...@bt.com>, Richard Heathfield <r...@see.sig.invalid> writes:
> Phred Phungus wrote:

>> Why did I need to add the -lm
>> when math.h was already included?
>
> There's no particular reason why adding a header should automatically
> link in its corresponding library (other than good sense, of course!);
> the GNU folk seem to think it makes sense to drive people nuts with
> stupid linker error messages, and no doubt they are, in some way,
> correct, although I can't for the life of me think in what way that
> might be.

They follow a technical standard. (I'm sure this answer qualifies as
"good enough" in this group.)


http://www.opengroup.org/onlinepubs/007908775/xcu/c89.html

----v----
-l m

This operand makes visible all functions referenced in <math.h>. An
implementation may search this library in the absence of this operand.
----^----


http://www.opengroup.org/onlinepubs/000095399/utilities/c99.html

----v----
-l m

This operand shall make visible all functions referenced in
<math.h>, <complex.h>, and <fenv.h>. An implementation may search this
library in the absence of this operand.
----^----


Cheers,
lacos

Ben Bacarisse

unread,
Feb 16, 2010, 6:18:02 AM2/16/10
to
la...@ludens.elte.hu (Ersek, Laszlo) writes:

> In article <zqGdnZnn14NXpufW...@bt.com>, Richard Heathfield <r...@see.sig.invalid> writes:
>> Phred Phungus wrote:
>
>>> Why did I need to add the -lm
>>> when math.h was already included?
>>
>> There's no particular reason why adding a header should automatically
>> link in its corresponding library (other than good sense, of course!);
>> the GNU folk seem to think it makes sense to drive people nuts with
>> stupid linker error messages, and no doubt they are, in some way,
>> correct, although I can't for the life of me think in what way that
>> might be.
>
> They follow a technical standard. (I'm sure this answer qualifies as
> "good enough" in this group.)

But they could follow the same technical standard by *not* requiring
the option as both your quotes make clear:

> http://www.opengroup.org/onlinepubs/007908775/xcu/c89.html
> ----v----
> -l m
>
> This operand makes visible all functions referenced in <math.h>. An
> implementation may search this library in the absence of this operand.
> ----^----
>
> http://www.opengroup.org/onlinepubs/000095399/utilities/c99.html
> ----v----
> -l m
>
> This operand shall make visible all functions referenced in
> <math.h>, <complex.h>, and <fenv.h>. An implementation may search this
> library in the absence of this operand.
> ----^----

<snip>
--
Ben.

Keith Thompson

unread,
Feb 16, 2010, 8:02:02 AM2/16/10
to
Richard Heathfield <r...@see.sig.invalid> writes:
> Phred Phungus wrote:
> <snip>
>
>> In compiling the drivers, I stumbled on a couple things:
>>
>> $ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out
>> dl2.c: In function ‘main’:

>> dl2.c:170: warning: missing braces around initializer
>
> gcc is warning you about a non-problem. The = {0} idiom is perfectly good C.
>
>> Why did I need to add the -lm when math.h was already included?
>
> There's no particular reason why adding a header should automatically
> link in its corresponding library (other than good sense, of course!);
> the GNU folk seem to think it makes sense to drive people nuts with
> stupid linker error messages, and no doubt they are, in some way,
> correct, although I can't for the life of me think in what way that
> might be.

Historical inertia, though fixing it wouldn't break anything or
violate any standard that I'm aware of.

In the Old Days, when linkers were less smart and memory less
plentiful than they are now, loading the math library could make
a program significantly bigger, both on disk and in memory. Not
loading it when it's not needed is an obvious optimization, but it
was left to the person invoking the compiler or linker to specify it.
And before the standard, there was nothing particularly special
about the math library as opposed to any other add-on library.
A choice had to be made about which library functions were part of
the standard library ("libc" or whatever), and which were optional
add-ons that the user had to specify. In the absence of a language
standard, making the math library optional made a lot of sense.

I don't think there's much excuse for keeping this behavior, though.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Alan Curry

unread,
Feb 16, 2010, 6:20:34 PM2/16/10
to
In article <ln4olhb...@nuthaus.mib.org>,

Keith Thompson <ks...@mib.org> wrote:
|
|Historical inertia, though fixing it wouldn't break anything or
|violate any standard that I'm aware of.

Which fix are you thinking of?

Note that any proposal which makes -lm magically unnecessary but doesn't do
the same for -lcurses -ltermcap, -ljpeg, -lusb, and so on will probably not
be taken seriously. You'd just be adding a special case to handle your own
pet peeve.

--
Alan Curry

Keith Thompson

unread,
Feb 16, 2010, 7:32:16 PM2/16/10
to
pac...@kosh.dhis.org (Alan Curry) writes:
> In article <ln4olhb...@nuthaus.mib.org>,
> Keith Thompson <ks...@mib.org> wrote:
> |
> |Historical inertia, though fixing it wouldn't break anything or
> |violate any standard that I'm aware of.
>
> Which fix are you thinking of?

Making "-lm" implicit, and letting the linker figure out whether
loading the math library is necessary.

> Note that any proposal which makes -lm magically unnecessary but doesn't do
> the same for -lcurses -ltermcap, -ljpeg, -lusb, and so on will probably not
> be taken seriously. You'd just be adding a special case to handle your own
> pet peeve.

The difference is that the math library is part of the C standard;
those other libraries are not.

A mechanism whereby, for example, the <curses.h> header contains a
directive that tells the linker to load libcurses.a (or whatever
it's called) might be a very good idea, and the same mechanism
could eliminate the need for "-lm". I suspect there are plenty
of implementations that do something like that. (A program that
declares, say, the sqrt function itself rather than via #include
<math.h> wouldn't see the directive; I'm not sure I care about
such programs.)

But in the meantime, I think a special-case fix for "-lm" would be
sufficiently useful in itself.

Alan Curry

unread,
Feb 16, 2010, 8:41:36 PM2/16/10
to
In article <lnvddwa...@nuthaus.mib.org>,

Keith Thompson <ks...@mib.org> wrote:
|
|The difference is that the math library is part of the C standard;
|those other libraries are not.

So what? Nobody writes a C implementation exclusively for programs conforming
to that standard. You're just arguing that an arbitrary list of functions
deserves special treatment because the list came out of your favorite
committee.

--
Alan Curry

Keith Thompson

unread,
Feb 16, 2010, 9:33:04 PM2/16/10
to

I don't find it at all arbitrary. If you do, that's fine with me.

Joe Wright

unread,
Feb 16, 2010, 9:49:51 PM2/16/10
to
Keith Thompson wrote:
> Richard Heathfield <r...@see.sig.invalid> writes:
>> Phred Phungus wrote:
>> <snip>
>>
>>> In compiling the drivers, I stumbled on a couple things:
>>>
>>> $ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out
>>> dl2.c: In function ‘main’:

>>> dl2.c:170: warning: missing braces around initializer
>> gcc is warning you about a non-problem. The = {0} idiom is perfectly good C.
>>
>>> Why did I need to add the -lm when math.h was already included?
>> There's no particular reason why adding a header should automatically
>> link in its corresponding library (other than good sense, of course!);
>> the GNU folk seem to think it makes sense to drive people nuts with
>> stupid linker error messages, and no doubt they are, in some way,
>> correct, although I can't for the life of me think in what way that
>> might be.
>
> Historical inertia, though fixing it wouldn't break anything or
> violate any standard that I'm aware of.
>
> In the Old Days, when linkers were less smart and memory less
> plentiful than they are now, loading the math library could make
> a program significantly bigger, both on disk and in memory. Not
> loading it when it's not needed is an obvious optimization, but it
> was left to the person invoking the compiler or linker to specify it.
> And before the standard, there was nothing particularly special
> about the math library as opposed to any other add-on library.
> A choice had to be made about which library functions were part of
> the standard library ("libc" or whatever), and which were optional
> add-ons that the user had to specify. In the absence of a language
> standard, making the math library optional made a lot of sense.
>
> I don't think there's much excuse for keeping this behavior, though.
>
Why would the math library be loaded. Surely only the functions declared
would be loaded. Or not? First, the linker knows nothing about <math.h> and
can't even smell it. It might see an unresolved call to sqrt() and with -lm
knows to also look in libm for it. I would hope the linker will 'load' only
the stuff required by sqrt(), not the whole math library. Or not?

--
Joe Wright
"If you rob Peter to pay Paul you can depend on the support of Paul."

Phred Phungus

unread,
Feb 16, 2010, 11:30:02 PM2/16/10
to


You can draw your own conclusions:

$ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -o out
dl2.c: In function ‘main’:


dl2.c:170: warning: missing braces around initializer

dl2.c:170: warning: (near initialization for ‘ThisCity.Nation’)


dl2.c:170: warning: missing initializer

dl2.c:170: warning: (near initialization for ‘ThisCity.CityName’)
/tmp/ccSI6Lnn.o: In function `CalcGreatCircleDistance':
dl2.c:(.text+0x303): undefined reference to `sin'
dl2.c:(.text+0x314): undefined reference to `sin'
dl2.c:(.text+0x32a): undefined reference to `cos'
dl2.c:(.text+0x33b): undefined reference to `cos'
dl2.c:(.text+0x351): undefined reference to `cos'
dl2.c:(.text+0x362): undefined reference to `cos'
dl2.c:(.text+0x378): undefined reference to `sin'
dl2.c:(.text+0x389): undefined reference to `sin'
dl2.c:(.text+0x39d): undefined reference to `acos'
collect2: ld returned 1 exit status


$ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out

dl2.c: In function ‘main’:


dl2.c:170: warning: missing braces around initializer

dl2.c:170: warning: (near initialization for ‘ThisCity.Nation’)


dl2.c:170: warning: missing initializer

dl2.c:170: warning: (near initialization for ‘ThisCity.CityName’)
$ ./out cityloc.txt >text3.txt
$

$ cat dl2.c
/* dllistmn.c - Test driver for double linked list lib
*
* DLLIST - Double-Linked List Library
*
* Copyright (C) 2000 Richard Heathfield
* Eton Computer Systems Ltd
* Macmillan Computer Publishing
*
* This program is free software; you can redistribute it
* and/or modify it under the terms of the GNU General
* Public License as published by the Free Software
* Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will
* be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General
* Public License along with this program; if not, write
* to the Free Software Foundation, Inc., 675 Mass Ave,
* Cambridge, MA 02139, USA.
*
* Richard Heathfield may be contacted by email at:
* bin...@eton.powernet.co.uk
*
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <math.h>
#include <assert.h>

#include "dllist.h"

#define PI 3.14159265358979323846

typedef struct CITY
{
char Nation[30];
char CityName[25];
double Latitude;
double Longitude;
} CITY;

int CompCities(const void *p1, const void *p2)
{
const CITY *c1 = p1, *c2 = p2;

return strcmp(c1->CityName, c2->CityName);
}

/* This function returns 1 on success,
* or 0 on error. If an error is detected,
* 0 is returned immediately, to simplify
* the code.
*/
int ParseCity(CITY *c, char *Buffer)
{
char *Token;
char *endp;

assert(c != NULL);

Token = strtok(Buffer, ",\n");

if(Token == NULL)
return 0;

strcpy(c->Nation, Token);

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

strcpy(c->CityName, Token);

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

c->Latitude = strtod(Token, &endp);

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

c->Latitude += strtod(Token, &endp) / 60.0;

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

if('S' == toupper(*Token))
{
c->Latitude *= -1.0;
}

c->Latitude *= PI;
c->Latitude /= 180.0;

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

c->Longitude = strtod(Token, &endp);

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

c->Longitude += strtod(Token, &endp) / 60.0;

Token = strtok(NULL, ",\n");
if(Token == NULL)
return 0;

if('E' == toupper(*Token))
{
c->Longitude *= -1.0;
}

c->Longitude *= PI;
c->Longitude /= 180.0;

return 1;
}

/* Calculate the distance between two points on the earth's
* surface (accurate to within around +/- 30 miles).
*
* Strictly speaking, this is nothing to do with data
* structures, classical or otherwise. Never mind -
* consider it a free gift. :-)
*/
int CalcGreatCircleDistance(CITY *City1, CITY *City2)
{
return (int)(3956.934132687 *
acos((sin(City1->Latitude) *
sin(City2->Latitude)) +
((cos(City1->Latitude) *
cos(City2->Latitude)) *
((cos(City1->Longitude) *
cos(City2->Longitude)) +
(sin(City1->Longitude) *
sin(City2->Longitude))))));
}

int Random(int n)
{
double d;

d = rand() / (RAND_MAX + 1.0);
d *= n;

return (int)d;
}

/* The test file cityloc.txt may be passed as argv[1]. */
int main(int argc, char *argv[])


{
DLLIST *List = NULL;
DLLIST *Safe = NULL;
CITY *City = NULL;
CITY ThisCity = {0};
CITY *TempCity = NULL;
CITY *First;
CITY *Second;

long TotalDistance;
int Distance;

int i;
int j;
int k;

int NumCities = 0;
int MaxCities = 0;

char Buffer[80] = {0};

FILE *fp = NULL;

srand((unsigned)time(NULL));
if(argc > 1)
{
fp = fopen(argv[1], "r");

if(NULL == fp)
{
printf("Can't open %s for reading.\n", argv[1]);
exit(EXIT_FAILURE);
}
}
else
{
puts("Please specify a cities file.");
exit(EXIT_FAILURE);
}

while(NULL != fgets(Buffer,
sizeof Buffer,
fp))
{
if(ParseCity(&ThisCity, Buffer))
{
if(++NumCities >= MaxCities)
{
++MaxCities;
MaxCities *= 3;
MaxCities /= 2;

TempCity = realloc(City,
MaxCities * sizeof *TempCity);
if(NULL == TempCity)
{
free(City);
fclose(fp);
puts("Out of memory.");
exit(EXIT_FAILURE);
}

City = TempCity;
}
memcpy(City + NumCities - 1,
&ThisCity,
sizeof *City);
}
}

fclose(fp);

TempCity = realloc(City, NumCities * sizeof *TempCity);
if(NULL == TempCity)
{
puts("Something odd is happening. realloc returned");
puts("NULL for a /reduction/ in storage.");
}
else
{
City = TempCity;
}

j = Random(NumCities - 6) + 6;

/* Build a random list of cities */
for(i = 0; i < j; i++)
{
k = Random(NumCities);

if(DL_SUCCESS != DLAddAfter(&List,
0,
City + k,
sizeof *City))
{
puts("Out of memory. Aborting.");
free(City);
DLDestroy(&List);

exit(EXIT_FAILURE);
}
}

Safe = List;

while(j > 1)
{
TotalDistance = 0;

First = DLGetData(List, NULL, NULL);

while(DLGetNext(List) != NULL)
{
List = DLGetNext(List);
Second = DLGetData(List, NULL, NULL);

Distance =
CalcGreatCircleDistance(First, Second);

printf("%s - %s : %d miles.\n",
First->CityName, Second->CityName, Distance);

TotalDistance += Distance;

First = Second;
}

printf("Total distance for this route: %ld miles.\n",
TotalDistance);

if(j > 2)
{
printf("---- Removing one city ----\n");
}

k = Random(j - 1);
for(i = 0; i < k; i++)
{
List = DLGetPrev(List);
}
DLDelete(List);

List = Safe;
--j;
}

/* Destroy the list */
DLDestroy(&List);

free(City);

return EXIT_SUCCESS;
}

// gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -o out
$


Typical output is:


Rostov on Don - Rio De Janeiro : 7047 miles.
Rio De Janeiro - New York : 4822 miles.
New York - Pittsburgh : 317 miles.
Pittsburgh - Sydney : 9616 miles.
Sydney - Bombay : 6303 miles.
Bombay - Belfast : 4711 miles.
Belfast - Rome : 1220 miles.
Rome - Lyon : 473 miles.
Lyon - Manila : 6684 miles.
Manila - Alma Ata : 3263 miles.
Alma Ata - New York : 6351 miles.
New York - Miami : 1096 miles.
Miami - Cayenne : 2335 miles.
Cayenne - Barcelona : 4190 miles.


So the calls that gcc had problem with none other than sin and cos. I
thought that the problem would be that floats really have floated away,
that is, C expects a double for everything as far as I can tell.
--
fred

Phred Phungus

unread,
Feb 16, 2010, 11:45:32 PM2/16/10
to
Richard Heathfield wrote:
> Phred Phungus wrote:
> <snip>
>
>> In compiling the drivers, I stumbled on a couple things:
>>
>> $ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out
>> dl2.c: In function �main�:
>> dl2.c:170: warning: missing braces around initializer
>
> gcc is warning you about a non-problem. The = {0} idiom is perfectly
> good C.

What is the warning trying to say? I do see braces and think that the
statement could be called one of initialization. Of what horrible thing
does it want to make me mindful?
--
fred

Phred Phungus

unread,
Feb 16, 2010, 11:57:34 PM2/16/10
to
Keith Thompson wrote:
> pac...@kosh.dhis.org (Alan Curry) writes:
>> In article <lnvddwa...@nuthaus.mib.org>,
>> Keith Thompson <ks...@mib.org> wrote:
>> |
>> |The difference is that the math library is part of the C standard;
>> |those other libraries are not.
>>
>> So what? Nobody writes a C implementation exclusively for programs conforming
>> to that standard. You're just arguing that an arbitrary list of functions
>> deserves special treatment because the list came out of your favorite
>> committee.
>
> I don't find it at all arbitrary. If you do, that's fine with me.
>

I enjoy spirited differences of informed opinion on threads of which I'm
OP, as they tend to teach me something.

I hope I understand that the -lm switch I require for gcc to find a
function such as sin is the only standard library that requires the
extra command-line switch.

I risk getting triple whooshed here, but I'd like to ask Alan among whom
a proposal to change something like this would air?

--
fred

Oliver Jackson

unread,
Feb 17, 2010, 1:24:54 AM2/17/10
to
On Feb 16, 5:41 pm, pac...@kosh.dhis.org (Alan Curry) wrote:
> In article <lnvddwaei7....@nuthaus.mib.org>,

BOOYA - finally some common sense! What I want to know is that how
come it took this long for you to rilize this. But welcome to the club
dog.They really ought a split the standard lib into lots of mini-libs
like stdio, stdlib, string, ..., - and then you keep the way and have
to type them all in again at linky time.

Keith Thompson

unread,
Feb 17, 2010, 1:28:10 AM2/17/10
to
Joe Wright <joeww...@comcast.net> writes:
> Keith Thompson wrote:
[...]

>> In the Old Days, when linkers were less smart and memory less
>> plentiful than they are now, loading the math library could make
>> a program significantly bigger, both on disk and in memory. Not
>> loading it when it's not needed is an obvious optimization, but it
>> was left to the person invoking the compiler or linker to specify it.
>> And before the standard, there was nothing particularly special
>> about the math library as opposed to any other add-on library.
>> A choice had to be made about which library functions were part of
>> the standard library ("libc" or whatever), and which were optional
>> add-ons that the user had to specify. In the absence of a language
>> standard, making the math library optional made a lot of sense.
>>
>> I don't think there's much excuse for keeping this behavior, though.
>>
> Why would the math library be loaded. Surely only the functions
> declared would be loaded. Or not? First, the linker knows nothing
> about <math.h> and can't even smell it. It might see an unresolved
> call to sqrt() and with -lm knows to also look in libm for it. I would
> hope the linker will 'load' only the stuff required by sqrt(), not the
> whole math library. Or not?

I'm actually not at all sure whether linkers generally load the
entire math library or just the necessary function(s). The behavior
probably varies from one linker to another, and my vague impression
is that older linkers would tend to load the entire library.
It might also vary depending on whether you're doing static or
dynamic linking.

Alan Curry

unread,
Feb 17, 2010, 1:43:20 AM2/17/10
to
In article <7u1b9v...@mid.individual.net>,

Phred Phungus <Ph...@example.invalid> wrote:
|
|I enjoy spirited differences of informed opinion on threads of which I'm
|OP, as they tend to teach me something.
|
|I hope I understand that the -lm switch I require for gcc to find a
|function such as sin is the only standard library that requires the
|extra command-line switch.
|
|I risk getting triple whooshed here, but I'd like to ask Alan among whom
|a proposal to change something like this would air?

Figure out what mechanism you want to propose, then write the patch that
implements it, then you'll know which pieces of the toolchain you've modified
and you can send the proposal to their mailing lists.

Proposal without patch has been done and ignored enough times already.

--
Alan Curry

Alan Curry

unread,
Feb 17, 2010, 2:21:22 AM2/17/10
to
In article <7u1ajd...@mid.individual.net>,

Phred Phungus <Ph...@example.invalid> wrote:
|
|What is the warning trying to say? I do see braces and think that the
|statement could be called one of initialization. Of what horrible thing
|does it want to make me mindful?

Mind that you don't accidentally provide an initializer of 8 values for a
struct that has 9 members, and everything gets the wrong value because you
added a member in the middle and forgot to update the initializer.

Designated initializers fix most of that. Note that gcc never gives the
"missing initializer" warning when designated initializers are used.

Note also that the "missing initializer" warning is in the -Wextra category,
which is reserved for the most nitpicky warnings.

Your programming style and your choice of warning flags should complement
each other, so you and your compiler work as a team, filling in each other's
weak spots. If you use big complicated initializers, and want the compiler to
always make sure they have the correct number of components, you enable this
warning, and the compiler does you the favor of telling you when the
initializer doesn't look like the thing being initialized. In return, you
compensate for the compiler's inability to read your mind by not using the
{0} shortcut when you happen to want an all-0 initializer.

--
Alan Curry

Nick Keighley

unread,
Feb 17, 2010, 3:31:23 AM2/17/10
to
On 17 Feb, 01:41, pac...@kosh.dhis.org (Alan Curry) wrote:
> In article <lnvddwaei7....@nuthaus.mib.org>,
> Keith Thompson  <ks...@mib.org> wrote:

> |The difference is that the math library is part of the C standard;
> |those other libraries are not.
>
> So what? Nobody writes a C implementation exclusively for programs conforming
> to that standard.

no, but /everyone/ writes a C implementation for programs conforming
to that standard!


> You're just arguing that an arbitrary list of functions
> deserves special treatment because the list came out of your favorite
> committee.

yes

Phred Phungus

unread,
Feb 17, 2010, 5:30:01 AM2/17/10
to
Nick Keighley wrote:
> On 17 Feb, 01:41, pac...@kosh.dhis.org (Alan Curry) wrote:
>> In article <lnvddwaei7....@nuthaus.mib.org>,
>> Keith Thompson <ks...@mib.org> wrote:
>
>> |The difference is that the math library is part of the C standard;
>> |those other libraries are not.
>>
>> So what? Nobody writes a C implementation exclusively for programs conforming
>> to that standard.
>
> no, but /everyone/ writes a C implementation for programs conforming
> to that standard!

I think you might emphasize /whichever standard/ instead of everyone.


>
>
>> You're just arguing that an arbitrary list of functions
>> deserves special treatment because the list came out of your favorite
>> committee.
>
> yes

I'm thinking that Alan could make a stronger case here, but then I still
risk that triple-whoosh.
--
fred

Phil Carmody

unread,
Feb 17, 2010, 5:38:53 AM2/17/10
to

When discussing use of a language defined by a particular committee,
there's _nothing_ arbitrary about using the output of that committee
in the context of that language to decide behaviour of the tools.

Phil
--
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1

Ben Bacarisse

unread,
Feb 17, 2010, 5:56:57 AM2/17/10
to
Phred Phungus <Ph...@example.invalid> writes:

> Richard Heathfield wrote:
>> Phred Phungus wrote:
>> <snip>
>>
>>> In compiling the drivers, I stumbled on a couple things:
>>>
>>> $ gcc dl1.o -D_GNU_SOURCE -Wall -Wextra dl2.c -lm -o out

>>> dl2.c: In function ‘main’:


>>> dl2.c:170: warning: missing braces around initializer
>>
>> gcc is warning you about a non-problem. The = {0} idiom is perfectly
>> good C.
>
> What is the warning trying to say? I do see braces and think that the
> statement could be called one of initialization. Of what horrible
> thing does it want to make me mindful?

It is telling you that the initialiser does not have enough "depth".
CITY is a struct containing two arrays and two numbers so gcc expects
an initialiser that looks like this:

{{0}, {0}, 0, 0}

(alternatively, {"", "", 0, 0}). If you simply add {}s and use {{0}}
gcc will tell you (with these selected warnings) that you are now
missing an initialiser.

--
Ben.

Phred Phungus

unread,
Feb 17, 2010, 6:17:52 AM2/17/10
to


I find linking difficult.

--

Eric Sosman

unread,
Feb 17, 2010, 9:29:22 AM2/17/10
to

This "they" of whom you speak: Who, exactly, are "they?"
"They" are certainly not the authors of the Standard, who took
a good deal of care *not* to specify how a C implementation is
invoked on any particular system. So the "they" who draw your
ire are ... well, who are "they?"

--
Eric Sosman
eso...@ieee-dot-org.invalid

Eric Sosman

unread,
Feb 17, 2010, 9:54:41 AM2/17/10
to
On 2/16/2010 9:49 PM, Joe Wright wrote:
> Keith Thompson wrote:
>> [...]

>> In the Old Days, when linkers were less smart and memory less
>> plentiful than they are now, loading the math library could make
>> a program significantly bigger, both on disk and in memory. [...]

>>
> Why would the math library be loaded. Surely only the functions declared
> would be loaded. Or not? First, the linker knows nothing about <math.h>
> and can't even smell it. It might see an unresolved call to sqrt() and
> with -lm knows to also look in libm for it. I would hope the linker will
> 'load' only the stuff required by sqrt(), not the whole math library. Or
> not?

No linker I can recall behaved exactly as Keith described:
They'd process the libraries they were told to look at, and pluck
from them only the pieces that were needed. If a library held a
bunch of stuff the program didn't ask for (directly or indirectly),
that stuff didn't end up in the program.

... but it still took time to process a library, and when disks
and CPU's were many times slower than they are today munching a
library could add significantly to the build time. Segregating
the math functions into their own library allowed the programs that
didn't need math to link with a library about (checks the DJGPP
installation) 25% smaller than if everything were included. Since
pretty much every program needed printf() and malloc() but only a
few needed atan2(), speeding up the link time for the majority was
a fairly easy optimization.

(There may also have been a desire to keep the two pieces apart
because the skill sets for writing numerical code as opposed to
"logical" code are somewhat different. The implementors of cosh()
may well have been separate from those who wrote setjmp(), and
using separate libraries might have allowed development schedules
to proceed without much interference. But that's just speculation
on my part; I wasn't there at the time.)

In any event, at least some implementations have already stuck
the math routines into the "primary" C library. Solaris, for
example, still has a libm -- but it's empty, and it's only there
so -lm flags in existing build scripts will work without complaint.
The math functions will actually be found in libc, along with puts()
and the rest, even if you don't say -lm on the command line.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Alan Curry

unread,
Feb 17, 2010, 5:10:31 PM2/17/10
to
In article <87pr449...@kilospaz.fatphil.org>,

Phil Carmody <thefatphi...@yahoo.co.uk> wrote:
|
|When discussing use of a language defined by a particular committee,
|there's _nothing_ arbitrary about using the output of that committee
|in the context of that language to decide behaviour of the tools.

"The tools", including gcc, glibc, binutils, and the corresponding non-GNU
equivalents on other unix-ish systems, are not designed as an implementation
of "the language" as you define it. They're designed to be the build system
for the entire OS. Conforming to the more narrowly-defined language standard
is only a bonus.

--
Alan Curry

Alan Curry

unread,
Feb 17, 2010, 5:13:10 PM2/17/10
to
In article <hlguhd$hh4$1...@news.eternal-september.org>,

I don't even know what imaginary group of people he's including me with in
the "you".

--
Alan Curry

Joe Wright

unread,
Feb 17, 2010, 6:31:00 PM2/17/10
to
Sanity at last.

Mark

unread,
Feb 17, 2010, 7:05:59 PM2/17/10
to
Eric Sosman wrote:
> ... but it still took time to process a library, and when disks
> and CPU's were many times slower than they are today munching a
> library could add significantly to the build time. Segregating
> the math functions into their own library allowed the programs that
> didn't need math to link with a library about (checks the DJGPP
> installation) 25% smaller than if everything were included. Since
> pretty much every program needed printf() and malloc() but only a
> few needed atan2(), speeding up the link time for the majority was
> a fairly easy optimization.
[snip]

That's a very clear explanation. Thank you very much.


--
Mark

Phil Carmody

unread,
Feb 17, 2010, 7:19:10 PM2/17/10
to

Blah, blah, blah. To be honest, with about ten words (maybe twelve)
Keith spoke more sense than the entirety of the above paragraph.

But I'm glad you finally recognise me as the one who actually
defined "the language", I've been waiting for such recognition
for years.

Keith Thompson

unread,
Feb 17, 2010, 8:53:38 PM2/17/10
to

Perhaps you could explain why requiring the user to use "-lm" when
using functions defined in the math library is better than *not*
requiring the user to use "-lm" when using functions defined in
the math library.

If libraries other than the math library can be used implicitly
as well, I have no problem with that, but the "-lm" requirement is
the one that seems to draw the most complaints from users.

Alan Curry

unread,
Feb 17, 2010, 9:25:06 PM2/17/10
to
In article <lnd4038...@nuthaus.mib.org>,

Keith Thompson <ks...@mib.org> wrote:
|
|Perhaps you could explain why requiring the user to use "-lm" when
|using functions defined in the math library is better than *not*
|requiring the user to use "-lm" when using functions defined in
|the math library.
|
|If libraries other than the math library can be used implicitly
|as well, I have no problem with that, but the "-lm" requirement is
|the one that seems to draw the most complaints from users.

Do you suppose that if people didn't run into -lm early in their
programming career, they'd never need to learn how the -l option works?
You can say yes if you think there are people whose programming career
consists solely of Standard C programs. I don't think such people exist.

It's a rite of passage for people learning how to compile and link (and
what the difference is between those 2 things). Everyone gets their turn
to see "undefined reference to sqrt", be confused for a while, and come
out smarter on the other side. If they didn't learn this way, they'd
have to learn later with something uglier like `gtk-config --libs`

--
Alan Curry

Keith Thompson

unread,
Feb 17, 2010, 10:32:09 PM2/17/10
to

So you advocate making a particular common operation gratuitously
difficult to teach people a lesson. Would it be even better to
require "-lstdio"?

If programmers don't just use standard C, they'll have to learn the
"-l" option (or equivalent) soon enough anyway.

Alan Curry

unread,
Feb 18, 2010, 1:07:46 AM2/18/10
to
In article <ln8war8...@nuthaus.mib.org>,

Keith Thompson <ks...@mib.org> wrote:
|
|So you advocate making a particular common operation gratuitously

A bit late for advocacy. I think this decision was made before I was born.

Just saying you don't really gain anything by changing it.

|difficult to teach people a lesson. Would it be even better to
|require "-lstdio"?

Separating stdio would provide a small benefit, probably even smaller than
the small benefit of separating libm. But it wouldn't be completely
unreasonable, especially for those projects whose goal is to produce a
"smaller libc".

But it would have to be linked by default, at least when the linker is
invoked via the cc/c89/c99 commands, because POSIX requires it to work that
way, and it would be a huge backward compatibility issue to require an option
that wasn't required before. This change would be breaking an existing
defined interface.

As far as the unix compiler command line interface is concerned, there's one
standard that actually applies, and The C Standard isn't it.

|
|If programmers don't just use standard C, they'll have to learn the
|"-l" option (or equivalent) soon enough anyway.

Right, so why put any effort into postponing it?

--
Alan Curry

Phred Phungus

unread,
Feb 18, 2010, 9:46:45 PM2/18/10
to

I agree, Mark. I'd curious to know how expensive it is to, say, link as
opposed to compile. Of course it's implementation and machine specific,
but I'd be curious what these numbers would look like with middle of the
road assumptions.
--
fred

bartc

unread,
Feb 19, 2010, 6:19:33 AM2/19/10
to

"Keith Thompson" <ks...@mib.org> wrote in message
news:lnfx509...@nuthaus.mib.org...
> Joe Wright <joeww...@comcast.net> writes:

>> Why would the math library be loaded. Surely only the functions

> I'm actually not at all sure whether linkers generally load the


> entire math library or just the necessary function(s). The behavior
> probably varies from one linker to another, and my vague impression
> is that older linkers would tend to load the entire library.
> It might also vary depending on whether you're doing static or
> dynamic linking.

Isn't that the very reason for the existence of linkers? That they pick and
choose the functions from each module that are strictly necessary?

Otherwise they would just be loaders (ie. a program, such as I once used,
which just loaded each module into memory, did a few fixups, and wrote out
an executable, all with no discernable overhead).

--
bartc

Ben Bacarisse

unread,
Feb 19, 2010, 7:22:12 AM2/19/10
to
"bartc" <ba...@freeuk.com> writes:

> "Keith Thompson" <ks...@mib.org> wrote in message
> news:lnfx509...@nuthaus.mib.org...
>> Joe Wright <joeww...@comcast.net> writes:
>
>>> Why would the math library be loaded. Surely only the functions
>
>> I'm actually not at all sure whether linkers generally load the
>> entire math library or just the necessary function(s). The behavior
>> probably varies from one linker to another, and my vague impression
>> is that older linkers would tend to load the entire library.
>> It might also vary depending on whether you're doing static or
>> dynamic linking.
>
> Isn't that the very reason for the existence of linkers? That they
> pick and choose the functions from each module that are strictly
> necessary?

It depends what you mean by "module". In C, a module is often taken
to be a translation unit, and many linkers were (and some are still)
not able to pick out a single function from a compiled translation
unit.

In the days when linkers were slow, there was an art to placing
groups of functions in translation units within a library so as to
balance the cost in time of linking many small modules against the
cost in wasted space of including functions that were not really
needed.

<snip>
--
Ben.

frank

unread,
Feb 21, 2010, 1:20:10 AM2/21/10
to
On Feb 17, 12:21 am, pac...@kosh.dhis.org (Alan Curry) wrote:
> In article <7u1ajdFam...@mid.individual.net>,

> Phred Phungus  <Ph...@example.invalid> wrote:
> |
> |What is the warning trying to say?  I do see braces and think that the
> |statement could be called one of initialization.  Of what horrible thing
> |does it want to make me mindful?
>
> Mind that you don't accidentally provide an initializer of 8 values for a
> struct that has 9 members, and everything gets the wrong value because you
> added a member in the middle and forgot to update the initializer.
>
> Designated initializers fix most of that. Note that gcc never gives the
> "missing initializer" warning when designated initializers are used.

What is a designated initializer?

Ben Bacarisse

unread,
Feb 21, 2010, 9:14:51 AM2/21/10
to
frank <abqha...@gmail.com> writes:

struct point { float x, y; };
struct point p = { .y = 4 };

or, for an array,

int scores[10] = { [5] = 42, 43, [9] = 99 };

This last initialises scores[5] to 42, scores[6] to 43 and scores[9]
to 99 (everything else is zeroed) but mixing designated and positional
initialisers like that is not good style.

--
Ben.

Message has been deleted
0 new messages