Is this a good habit?

J

Jalapeno

Ancient_Hacker said:
Richard said:
Ancient_Hacker said:


Translation: most of those you've encountered.


Okay, how's about you compile this little program and tell us the size
of the obj and executable files:

int a[1000000];

int main( int argc, char * argv[] ) {

a[1] = 99;
printf("%d\n", A[1] );
return 0;
}

ERROR CCN3045 T9232EH.SOURCE.C(AC):6 Undeclared identifier A.

WARNING CCN3304 T9232EH.SOURCE.C(AC):6 No function prototype given
for "printf".

INFORMATIONAL CCN3410 T9232EH.SOURCE.C(AC):8 The automatic variable
"A" is defined but never referenced.

INFORMATIONAL CCN3414 T9232EH.SOURCE.C(AC):8 The parameter "argv"
is never referenced.

INFORMATIONAL CCN3414 T9232EH.SOURCE.C(AC):8 The parameter "argc"
is never referenced.

CCN0793(I) Compilation failed for file //'T9232EH.SOURCE.C(AC)'.
Object file not created.
 
A

Ancient_Hacker

Richard said:
int a[1000000];

Stop right there. No implementation is obliged to support an object that
size.

Thanks once again for the disengenuous comeback.

One might surmise that you know the purpose, or actually, purposes of
my typing 1 million in that spot.

(1) If the compiler has a 16-bit restriction on array sizes, we learn
of it right away.

(2) if the compiler accepts it, and the linker does too, then we know
this is most likely a 32-bit address space or wider system. That's
useful info in and of itself.

(3) If the object and exe files are a few tens of K larger than 2 or 4
or 8 meg, then we've learned that this C system is really lame, at
least under the4 default compile/link options. If the object and exe
files are much much smaller than 1 meg, typically a few tens of
kilobytes, then we've learned the original poster need not worry too
much about uninitialized static variables. If we'd chosen a much
smaller number, such as 1000, then it would be hard to tell just from
the size of the files how the C system handled uninitialized variables.
 
A

Ancient_Hacker

Jalapeno said:
ERROR CCN3045 T9232EH.SOURCE.C(AC):6 Undeclared identifier A.

WARNING CCN3304 T9232EH.SOURCE.C(AC):6 No function prototype given
for "printf".

INFORMATIONAL CCN3410 T9232EH.SOURCE.C(AC):8 The automatic variable
"A" is defined but never referenced.

INFORMATIONAL CCN3414 T9232EH.SOURCE.C(AC):8 The parameter "argv"
is never referenced.

INFORMATIONAL CCN3414 T9232EH.SOURCE.C(AC):8 The parameter "argc"
is never referenced.

CCN0793(I) Compilation failed for file //'T9232EH.SOURCE.C(AC)'.
Object file not created.


How about you try again, after making the trivial and all so obvious
changes?
 
G

goose

Snis said:
Hi,

It seems pretty common to return pointers to a static array, for
example:

char *capitalize( char *name )
{
static char buf[MAX_STRING_LENGTH];

sprintf( buf, "%s", name );
if ( *buf >= 'a' && *buf <= 'z' )
*buf += 'A' - 'a';

return buf;
}

But when I do something like this, I like to instead keep a static
pointer and malloc it the first time, to save space in whatever bank
static memory is stored in, since I have this vague idea that if too
much space is used in static memory bad things will happen? So I do
this instead:

char *capitalize( char *name )
{
static char *buf;

if ( !buf )
{
buf = malloc( MAX_STRING_LENGTH );
if ( !buf ) return name;
}

sprintf( buf, "%s", name );
if ( *buf >= 'a' && *buf <= 'z' )
*buf += 'A' - 'a';

return buf;
}

Here is how I analyze both methods as far as efficiency:

* the 2nd version uses less space in delicate "static memory" (not sure
what that's called)

Only until it is called.
* the 1st is much faster on the first call
* the 1st is slightly faster the other calls (assuming the first time,
malloc worked)
* the 1st does not assume the OS will do appropriate cleanup on exit,
as the 2nd does
* the 1st is quicker to type

I wonder which method is really best. I suppose it depends on how big
MAX_STRING_LENGTH is. I assume for instance one wouldn't want to
casually declare multi-hundred-kilobyte static arrays?

I'd generally go with the first method (if forced too, at gunpoint
by the people holding my salary check hostage) because I work
with embedded systems and would rather have the application not
load at all than load and fail with a memory error (which tends
to confuse the poor user).

The first way, I know in advance that I'm exceeding my memory
constraints. The second way could load just fine but the testers
might not ever execute an action that could cause the malloc,
and I won't know that I'm out of memory until 20000 devices are
in the field and the *user* executes it.

That said, if I were free to chhose, I would write this function
like so:

int capitalise (char *dst, char *src);

This way I can seperate the functions functionality
from the memory management and be able to return an
error value independent of the return string i.e.
I could return any one of a couple of #defined error
values instead of only NULL.

goose,
 
M

Michael Wojcik

Okay, how's about you compile this little program and tell us the size
of the obj and executable files:

How breathtakingly irrelevant. Not, apparently, an ancient
rhetorician, in any event.
I've probably had the acquaintance of a dozen C compilers over the
centuries, and I don't recall a one that was quite this clunky.

I'm sorry, but this isn't clear. Are you claiming that "a dozen C
compilers" constitutes "most C implementations", or are you admitting
that Richard was correct?

--
Michael Wojcik (e-mail address removed)

Unlikely prediction o' the day:
Eventually, every programmer will have to write a Java or distributed
object program.
-- Orfali and Harkey, _Client / Server Programming with Java and CORBA_
 
W

websnarf

Snis said:
EventHelix.com said:
Snis said:
It seems pretty common to return pointers to a static array, for
example:

char *capitalize( char *name ) {
static char buf[MAX_STRING_LENGTH];
sprintf( buf, "%s", name );
if ( *buf >= 'a' && *buf <= 'z' )
*buf += 'A' - 'a';
return buf;
}

IMHO, Use of static variables inside functions is not a good idea. You
will end up with code that is not thread safe. The function will
misbehave if multiple concurrently running threads are invoking the
function with static variables.

Yes, of course, it goes without saying in either case one must exercise
caution.
IMHO one of the most beautiful things about C is that it allows you
such flexibility. It does not assume you are a baby and hold your
hand.
If I wanted a language where various people told me "Oh you can't do
that, it's too dangerous", I would program Java =) Thanks for the word
of warning anyway, though.

What the hell is *WRONG* with you people. Review what EventHelix is
saying. If you need to run in a multithreaded environment then static
solution *CANNOT WORK*. Let me repeat: *CANNOT WORK*.

So you take this piece of information and you go on some diatribe about
how you are so grateful for the fact that C lets you code things that
in some contexts *CANNOT WORK*?
I will continue to return pointers to static arrays in time sensitive
functions because I am, and those who work under me are, smart enough
to know what we're doing. =)

Really? Unless the static is read-only, or you are in the module
containing main(), I would never do this -- because I figure I am
"smart enough" to know better. If you want to avoid the allocation
costs, then you can *pass in* the buffers you want to be used -- in
that way you retain the performance, and there is no multithreading
issue. Its a question of scalability -- if you need to think hard
about every piece of code you use (in this case knowing that you can't
use the function while multithreading), then that's time and energy
taken away from thinking hard about other programming details, like
architecture/design.

I'm not sure this occurred to K&R (and T) when they originally designed
C and Unix (the counter evidence in the std library seems overwhelming)
but what you should celebrate is that they don't *force* you to make
this kind of mistake. I guess its a moot point since you *are* making
the mistake anyways.
 
J

Jalapeno

Ancient_Hacker said:
How about you try again, after making the trivial and all so obvious
changes?

Sure, how about posting compilable code if you want us to compile it.



5694A01 V1 R6 z/OS C 'T9232EH.SOURCE.C(AC)'


E X T E R N A L S Y M B O L D I C T I O N A R Y


NAME TYPE ID ADDR LENGTH


PC 1 000000 000108
MAIN LD 0 000018 000001
PRINTF ER 4 000000
CEEMAIN SD 6 000000 00000C
MAIN ER 8 000000

A SD 2 000000 3D0900 <--<< lookee
CEESG003 ER 3 000000
CEESTART ER 5 000000
EDCINPL ER 7 000000



* * * * * E N D O F C O M P I L A T I O N



z/OS V1 R6 BINDER 10:47:28 THURSDAY JULY 27, 2006

BATCH EMULATOR JOB(T9232EHA) STEP(STEP1) PGM=IEWL PROCEDURE(LKED)
IEW2278I B352 INVOCATION PARAMETERS - AMODE=31,MAP



*** M O D U L E M A P ***

---------------

CLASS B_TEXT
LENGTH = 3D1402 <--<< lookee
ATTRIBUTES = CAT,
LOAD, RMODE=ANY
OFFSET = 0 IN SEGMENT 001 ALIGN = DBLWORD
---------------


SECTION CLASS ------- SOURCE --------
OFFSET OFFSET NAME TYPE LENGTH DDNAME SEQ MEMBER

0 CEESTART CSECT 7C SYSLIN 01 **NULL**

80 $PRIV000010 CSECT 108 SYSLIN 01 **NULL**
18 98 MAIN LABEL

lookee >>--> 188 A CSECT 3D0900 SYSLIN 01 **NULL**

3D0A88 CEEMAIN CSECT C SYSLIN 01 **NULL**

3D0A98 CEESG003 * CSECT 12B SYSLIB 01 CEESG003

3D0BC8 EDCINPL * CSECT 24 SYSLIB 01 EDCINPL

3D0BF0 PRINTF * CSECT A SYSLIB 01 PRINTF

3D0C00 CEEROOTA * CSECT 1F0 SYSLIB 01 CEEROOTA
0 3D0C00 CEEROOTD LABEL

3D0DF0 CEEBETBL * CSECT 28 SYSLIB 01 CEEBETBL

3D0E18 CEEBPUBT * CSECT 70 SYSLIB 01 CEEBPUBT

3D0E88 CEEBTRM * CSECT A4 SYSLIB 01 CEEBTRM

3D0F30 CEEBLLST * CSECT 5C SYSLIB 01 CEEBLLST
10 3D0F40 CEELLIST LABEL

3D0F90 CEEBINT * CSECT 8 SYSLIB 01 CEEBINT

3D0F98 CEEARLU * CSECT B0 SYSLIB 01 CEEARLU

3D1048 CEEBPIRA * CSECT 2D8 SYSLIB 01 CEEINT
0 3D1048 CEEINT LABEL
0 3D1048 CEEBPIRB LABEL
0 3D1048 CEEBPIRC LABEL

3D1320 CEECPYRT * CSECT E2 SYSLIB 01 CEEINT

SAVE OPERATION SUMMARY:

MEMBER NAME GO
LOAD LIBRARY SYS06208.T104725.RA000.T9232EHA.GOSET.H01
PROGRAM TYPE LOAD MODULE
VOLUME SERIAL
MAX BLOCK 32760
DISPOSITION ADDED NEW
TIME OF SAVE 10.47.29 JUL 27, 2006


SAVE MODULE ATTRIBUTES:

AC 000
AMODE 31
DC NO
EDITABLE YES
EXCEEDS 16MB NO
EXECUTABLE YES
MIGRATABLE YES
OL NO
OVLY NO
PACK,PRIME NO,NO
PAGE ALIGN NO
REFR NO
RENT NO
REUS NO
RMODE ANY
SCTR NO
SSI
SYM GENERATED NO
TEST NO
XPLINK NO
MODULE SIZE (HEX) 003D1408 <--<< lookee




Menu Functions Confirm Utilities Help
--------------------------------------------------------------------
VIEW T9232EH.Z.LOAD Row 00001 of 00003
Command ===> Scroll ===> CSR
Name Prompt Alias-of Size TTR AC AM RM
_________ AC 003D1408 000016 00 31 ANY
**End**
/ \
|
lookee ----------------------------+


I think perhaps you should be asking questions in this newsgroup
instead of answering them.
 
W

websnarf

Ancient_Hacker said:
Richard said:
Ancient_Hacker said:
Translation: most of those you've encountered.

Okay, how's about you compile this little program and tell us the size
of the obj and executable files:

int a[1000000];
int main( int argc, char * argv[] ) {
a[1] = 99;
printf("%d\n", A[1] );
return 0;
}

I would LOVE to learn what C compilers are so poorly conceived as to
emit uninitialized static data as initialized data.

Actually a utility called "CauseWay", which is a DOS extender and
linker for WATCOM C/C++ would expand out the BSS segment to the
sequence of zeros at link time. While this seems like an insane thing
to do, it was a moot point, because their linker also comes with an
exe-compressor which detects and squashes these segments down to
nothing anyways. Its actually only an issue with compile times, since
the linker has to generate these big spaces, then the compressor has to
squash them back down.
I've probably had the acquaintance of a dozen C compilers over the
centuries, and I don't recall a one that was quite this clunky. I'd
love to learn of counterexamples.

Well, as I point out above -- the issue is with the *linker* and
compiler.
 
A

Ancient_Hacker

I think perhaps you should be asking questions in this newsgroup
instead of answering them.


Sigh. And I think you should be following the suggestions above,
instead of printing out irrelevant link maps.

I suggested you show us the size of the obj and exe files. Surely your
system has a "dir"-like command?

The numbers shown on the link map are irrelevant. Of course the
lengths are going to be correct, they couldnt be otherwise. The
question is, did the compiler and linker emit four or eight million
zeroes, or did they emit "reserve 4000000 bytes".

Even if your particular compiler/linker are so brain-damaged as to
write out megabytes of zeroes, that doesnt impact the original poster's
question, as it's unlikely his embedded application runs or will ever
run on a IBM mainframe.
 
A

Ancient_Hacker

Michael Wojcik wrote:

I'm sorry, but this isn't clear. Are you claiming that "a dozen C
compilers" constitutes "most C implementations",

We've been over this before. I've been saddled with using C since the
very early days, so it's been my misfortune to intimately know Unix V6
C, Venix C, Mark Williams C, a 1979 Intel C (urp), Microsoft and
Borland C's since versions 1.0, Convergent C, and so on and bloodily
so forth thru early Sun, SGI, HP/UX, AIX, and other C's. I don't
recall a one that emitted long chunks of zeroes when it didnt have to.
And as others have mentioned, even that isnt a sure way to determine if
the executable is going to be bloated, thanks to exe compressors. And
even that doesnt tell us what the poor original poster wanted to know.








or are you admitting
 
K

Keith Thompson

Ancient_Hacker said:
How about you try again, after making the trivial and all so obvious
changes?

How about you post compilable code in the first place, rather than
insisting that others do your work for you? If you can't be bothered
to take the time to compile your own code yourself before posting, I
certainly can't be bothered to fix it.

Yes, turning what you posted into something compilable is nearly
trivial. So take the time to do it yourself. We'll be glad to point
out your errors, but we're not here to fix them for you (unless
perhaps the errors are the point of a post, which these weren't).

In any case, a single example compiled on a single implementation
doesn't really prove anything. Upthread, you wrote:

| uninitialized static memory is, in most C implementations, not emitted
| as a long array of zeroes, but just as a note to the linker or C
| sraretup code to add xxx bytes to the zero-initialized "BSS" segment.
| So these variables do not make the executable file any longer.

and Richard quite correctly replied:

| Translation: most of those you've encountered.

It may well also be true of most, or even all, C implementations that
Richard has encountered, or that I've encountered. We may or may not
be able to come up with an implementation that doesn't behave the way
you described (though I seriously doubt that all implementation have
something called a "BSS segment"). The point is that we discuss the
*language* here, not (mostly) specific implementations of it. If you
want to talk about BSS segments and other things that are not defined
by the C language (and that, where they exist, are not C-specific),
there are places to do so.
 
K

Keith Thompson

What the hell is *WRONG* with you people. Review what EventHelix is
saying. If you need to run in a multithreaded environment then static
solution *CANNOT WORK*. Let me repeat: *CANNOT WORK*.

So you take this piece of information and you go on some diatribe about
how you are so grateful for the fact that C lets you code things that
in some contexts *CANNOT WORK*?

Stop shouting.

Not all code needs to worry about being used in a multithreading
environment.
 
F

Flash Gordon

Ancient_Hacker said:
Michael Wojcik wrote:



We've been over this before. I've been saddled with using C since the
very early days, so it's been my misfortune to intimately know Unix V6
C, Venix C, Mark Williams C, a 1979 Intel C (urp), Microsoft and
Borland C's since versions 1.0, Convergent C, and so on and bloodily
so forth thru early Sun, SGI, HP/UX, AIX, and other C's.

Yes, you've made that claim before. with reference to how to write a
macro that behaved like sizeof. All the macros you provided broke on the
compilers I have easy access to even *after* you corrected a problem.
> I don't
recall a one that emitted long chunks of zeroes when it didnt have to.
And as others have mentioned, even that isnt a sure way to determine if
the executable is going to be bloated, thanks to exe compressors. And
even that doesnt tell us what the poor original poster wanted to know.

You suggested lots of things that are not necessarily true. For example
suggesting that the size of the bss section will not be limited and
won't affect other things. Well, I've news for you, on Linux limits can
be set for the size of the bss section and for the total memory of a
process. If you are not the administrator of the box you won't be able
to change any global limits that have been set up.
 
A

Ancient_Hacker

Flash said:
Yes, you've made that claim before. with reference to how to write a
macro that behaved like sizeof. All the macros you provided broke on the
compilers I have easy access to even *after* you corrected a problem.

Sorry to hear you were unable to see the very obvious fix of putting
(char *) before each pointer. Also sorry to see you tend to hang onto
old grudges that were'nt worth grumbling about in the first place.

You suggested lots of things that are not necessarily true. For example
suggesting that the size of the bss section will not be limited and
won't affect other things.

Sorry to see you have trouble with reading and comprehension, not to
mention simple logic and analysis. The fella was talking about an
embedded application, so administrator-set limits are not a problem, as
he *is* the administrator, plus unlikely to be running Linux on that
wristwatch or whatnot.. And he was inquiring about like 80 byte
arrays, not your typical multi-megabyte admin limits. And our test was
mainly to see if there was a 16-bit limit. You may remember the
horrible 80's and 90's when most of us were always slamming against a
16-bit limit or another. Once past that limit, its mostly clear
sailing.
 
C

Chris Torek

We've been over this before. I've been saddled with using C since the
very early days, so it's been my misfortune to intimately know Unix V6
C, Venix C, Mark Williams C, a 1979 Intel C (urp), Microsoft and
Borland C's since versions 1.0, Convergent C, and so on and bloodily
so forth thru early Sun, SGI, HP/UX, AIX, and other C's. I don't
recall a one that emitted long chunks of zeroes when it didnt have to.

I do.

(In a similar, but not quite identical, case, the VMS C compiler used
to turn:

switch (x) {
case 0: zerostuff(); break;
case 32767: maxstuff(); break;
default: general(); break;
}

into a whopping executable with every possible value in 0..32767
actually enumerated.)
And as others have mentioned, even that isnt a sure way to determine if
the executable is going to be bloated, thanks to exe compressors.

Indeed. (I believe ARM had an interesting paging-specific compressed
binary format.)

The point is, you have made unsupported claims, and incorrect claims,
and then complained about the fact that people have pointed out that
they are unsupported and/or incorrect.

(Some of your unsupported claims are, in my experience, true. That
does not make them supported. You could avoid a lot of problems by
adding "in my experience" or similar weasel-words; or, in this
particular case, you could simply have said that one should try
to avoid implementations that generate poor code and/or executables,
since there is now usually a choice here.)
 
A

Ancient_Hacker

Chris said:

No, you don't. Otherwise you would have mentioned it. What you diod
instead is give an example of something completely different:
(In a similar, but not quite identical, case, the VMS C compiler used
to turn:

switch (x) {
case 0: zerostuff(); break;
case 32767: maxstuff(); break;
default: general(); break;
}

into a whopping executable with every possible value in 0..32767
actually enumerated.)

hat case has nothing to do with BSS storage. In your case the compiler
had to generate INITIALIZED data, either a table of jump addresses, or
a table of jump instructions. In either case, that's nothing like
uninitialized storage. Yes, it's an examlpe of a compiler doing a dumb
thing. In that case the compiler should have chosen to generate soem
if tests, or a short table of value/address pairs, only two entries
long. But it's not in any way what we were discussing. So thanks for
the verification, neither one of us has seen a compiler that generates
all those zeroes instead of a simple BSS.


That's why I carefully specified that one should print out the length
of *both* the object file and the executable.

The point is, you have made unsupported claims, and incorrect claims.

Please feel free to start straightening me out. Any time now.

,
and then complained about the fact that people have pointed out that
they are unsupported and/or incorrect.

I do get a bit miffed by folks that are consistently intellectually
dishonest.
Some people go to great lengths to ignore reality and hold to very
narrow views. I've found those attitudes to be unhelpful.

(Some of your unsupported claims are, in my experience, true. That
does not make them supported.

What the H*ll does that mean? If they're true in your experience, how
can that not be support? Sounds like a very fine distinction.

You could avoid a lot of problems by
adding "in my experience" or similar weasel-words;


How could anything be NOT "in my experience"?
or, in this
particular case, you could simply have said that one should try
to avoid implementations that generate poor code and/or executables,
since there is now usually a choice here.)

I'm not into begging the question or stating the obvious.
I will let the original poster judge whose comments were more apt.
 
A

Ancient_Hacker

Well, as I point out above -- the issue is with the *linker* and
compiler.

Worse than that-- it depends on the two, plus on the actions of the
usual "cl" launcher that runs the two and passes and mangles options
between them, plus it dfepends on options the options passed to one or
both, plus as someone mentioned, there were exe-packer programs
especially made to post-fix these bloated exe files. Not to mention
some frugal OS's has program loaders that knew about exe files with
allocation holes in them. Lots of possible interactions. Can we
discuss something simpler like brain surgery?
 
M

Mark McIntyre

Sigh. And I think you should be following the suggestions above,
instead of printing out irrelevant link maps.

I suggested you show us the size of the obj and exe files.

Apparently you're unfamiliar with mainframe OSen. Heck, even on a Vax
(which aint no mainframe) the size of the executable on disk was
irrelevant, and rounded to the nearest 512 to boot.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
M

Mark McIntyre

Sorry to hear you were unable to see the very obvious fix of putting
(char *) before each pointer.

So lets get this straight: /you/ wrote broken buggy code which failed
to do what you claimed, and somehow thats someone else's fault.

Theres a pretty important rule round here: post correct code, or
expect to get ripped to shreds.
Sorry to see you have trouble with reading and comprehension, not to
mention simple logic and analysis.

And being abusive to regulars won't help you either.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
A

Ancient_Hacker

Mark said:
Apparently you're unfamiliar with mainframe OSen. Heck, even on a Vax
(which aint no mainframe) the size of the executable on disk was
irrelevant, and rounded to the nearest 512 to boot.

I'd consider CDC 6600's, 7600's, Vax 11/780's (Which was definitely a
mainframe, at least in size) as "mainframes". I don't know what you
mean about the size of the executable being irrelevant. We were trying
to determine whether uninitialized static data was written out as a run
of zeroes. That point is not irrelevant to the original poster, indeed
it was the nub of his crux.

And the biz about "rounded" is pointless-- most OS's allocate files by
the block. That has nothing at all to do with the subject under
discussion. And the "nearest" 512? makes it kinda hard to run half
the programs.
 

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
473,764
Messages
2,569,567
Members
45,042
Latest member
icassiem

Latest Threads

Top