From: Paul Rubin on
Gregory Ewing <greg.ewing(a)canterbury.ac.nz> writes:
> I don't think it was as stupid as that back when C was
> designed. Every byte of memory was precious in those days,
> and if you had, say, 10 bytes allocated for a string, you
> wanted to be able to use all 10 of them for useful data.

No I don't think so. Traditional C strings simply didn't carry length
info except for the nul byte at the end. Most string functions expected
the nul to be there. The nul byte convention (instead of having a
header word with a length) arguably saved some space both by eliminating
a multi-byte header and by allowing trailing substrings to be
represented as pointers into a larger string. In retrospect it seems
like a big error.
From: Lawrence D'Oliveiro on
In message <mailman.2231.1277700501.32709.python-list(a)python.org>, Kushal
Kumaran wrote:

> On Sun, Jun 27, 2010 at 5:16 PM, Lawrence D'Oliveiro
> <ldo(a)geek-central.gen.new_zealand> wrote:
>
>>In message <mailman.2184.1277626565.32709.python-list(a)python.org>, Kushal
>> Kumaran wrote:
>>
>>> On Sun, Jun 27, 2010 at 9:47 AM, Lawrence D'Oliveiro
>>> <ldo(a)geek-central.gen.new_zealand> wrote:
>>>
>>>> A long while ago I came up with this macro:
>>>>
>>>> #define Descr(v) &v, sizeof v
>>>>
>>>> making the correct version of the above become
>>>>
>>>> snprintf(Descr(buf), foo);
>>>
>>> Not quite right. If buf is a char array, as suggested by the use of
>>> sizeof, then you're not passing a char* to snprintf.
>>
>> What am I passing, then?
>
> Here's what gcc tells me (I declared buf as char buf[512]):
> sprintf.c:8: warning: passing argument 1 of 'snprintf' from
> incompatible pointer type
> /usr/include/stdio.h:363: note: expected 'char * __restrict__' but
> argument is of type 'char (*)[512]'
>
> You just need to lose the & from the macro.

Why does this work, then:

ldo(a)theon:hack> cat test.c
#include <stdio.h>

int main(int argc, char ** argv)
{
char buf[512];
const int a = 2, b = 3;
snprintf(&buf, sizeof buf, "%d + %d = %d\n", a, b, a + b);
fprintf(stdout, buf);
return
0;
} /*main*/
ldo(a)theon:hack> ./test
2 + 3 = 5

From: Lawrence D'Oliveiro on
In message <pan.2010.06.27.13.55.04.500000(a)nowhere.com>, Nobody wrote:

> On Sun, 27 Jun 2010 14:36:10 +1200, Lawrence D'Oliveiro wrote:
>
>> Except nobody has yet shown an alternative which is easier to get right.
>
> For SQL, use stored procedures or prepared statements.

So feel free to rewrite my example using either stored procedures or
prepared statements, to prove how much easier it is.
From: Roy Smith on
In article <7xmxuffpxp.fsf(a)ruckus.brouhaha.com>,
Paul Rubin <no.email(a)nospam.invalid> wrote:

> Gregory Ewing <greg.ewing(a)canterbury.ac.nz> writes:
> > I don't think it was as stupid as that back when C was
> > designed. Every byte of memory was precious in those days,
> > and if you had, say, 10 bytes allocated for a string, you
> > wanted to be able to use all 10 of them for useful data.
>
> No I don't think so. Traditional C strings simply didn't carry length
> info except for the nul byte at the end. Most string functions expected
> the nul to be there. The nul byte convention (instead of having a
> header word with a length) arguably saved some space both by eliminating
> a multi-byte header and by allowing trailing substrings to be
> represented as pointers into a larger string. In retrospect it seems
> like a big error.

Null-terminated strings predate C. Various assembler languages had
ASCIIZ (or similar) directives long before that.

The nice thing about null-terminated strings is how portable they have
been over various word lengths. Life would have been truly inconvenient
if K&R had picked, say, a 16-bit length field, and then we needed to
bump that up to 32 bits in the 80's, and again to 64 bits in the 90's.
From: Steven D'Aprano on
On Mon, 28 Jun 2010 20:55:53 -0400, Roy Smith wrote:

> The nice thing about null-terminated strings is how portable they have
> been over various word lengths. Life would have been truly inconvenient
> if K&R had picked, say, a 16-bit length field, and then we needed to
> bump that up to 32 bits in the 80's, and again to 64 bits in the 90's.

Or a Pascal 8 bit length field.

However the cost of null-terminated strings is that they can't store
binary data, and worse, they're slow. In fact, according to some, null-
terminated strings are the *worst* way to implement a string type.

http://www.joelonsoftware.com/articles/fog0000000319.html



--
Steven