From: "David Thompson" <david.thompson1@worldnet.att.net>
Subject: C strings, was Re: Ada Idioms Progress Preview
Date: Tue, 21 Aug 2001 05:54:21 GMT
Date: 2001-08-21T05:54:21+00:00 [thread overview]
Message-ID: <hImg7.54453$gj1.4996625@bgtnsc05-news.ops.worldnet.att.net> (raw)
In-Reply-To: 3B787A30.F806DB00@home.com
Warren W. Gay VE3WWG <ve3wwg@home.com> wrote :
> .... There are C programs that work with
> fixed sized strings, like Ada, though this tends to be rarer (it
> sometimes is done with embedded SQL/C). If you then need to pass
> the fixed string to a printf() or other function that expects a
> "C string", then yes, this then becomes a problem (just as it does
> for Ada supplying a string for C).
>
Actually either truly fixed, or with (variable) length specified
by means other than null-termination such as a separate count.
That's an unfortunate example; for printf in particular, at least
for a data argument not the format string, this is easily handled
by the "precision" modifier e.g. %.20s or %.*s if variable.
For the many other library and user/3rd-party functions
expecting a C (null-terminated) string your point stands.
As discussed elsethread I believe, in C++ you also have
the option of std::string which effective keeps the separate
count and dynamically allocates for you, with methods and
standard functions thereon including converstion to C-string.
...
> OK, you're saying when you pass arrays into a C function, when
> the array is declared external to that function. Something like:
>
> void func2(char *str) {
> // what is the array size of str?
> }
> void func1() {
> char my_array[31];
> func2(my_array);
> }
>
> This is a weakness, but if you know that func2() should work
> with fixed length arrays of a certain size, you can use:
>
> void func2(char str[31]) {
> // what is the array size of str?
> }
>
> instead. However, I agree that this is feeble, compared to the
> way Ada passes array bounds information.
>
...
> OK, it sounds like you're suggesting the following:
>
> void my_func(char *str) {
> int slen = sizeof str; // which does not make sense
>
> But this is nonsense anyway - no self respecting C programmer would
> do this, because you are obviously asking for the size of the pointer ;-)
>
> However, if you declared this instead:
>
> void my_func(char str[31]) {
> int array_len = sizeof str; // this comes close to size of array
>
> (on many platforms : array_len=32 here due to padding)
>
NO! In C (or C++) a function parameter declared apparently as an array
IS a pointer. Any bound given is ignored <PEDANTIC>except that,
at least in C99, if the bound is constant and nonpositive it is clearly
a constraint violation, in C90 it was not clear if 6.7.1 adjustment
occurred before 6.1.2.5 array type nonempty, and wasn't
a mandatory diagnostic anyway; and in C99 if you specify
'static' in the brackets (its fourth! overloaded meaning),
you promise to call only with pointers that are in fact to arrays
of _at least_ that many elements, allowing some optimizations;
but even so:</>
The type IS pointer, and sizeof(str) IS that of pointer.
Full stop. C FAQ 6.4, 6.21.
What you can do in C if you really want bounds matching is
void func2( char (*strp)[31]) {
/* array is *strp elements are (*strp)[i] */
/* sizeof(*strp) is 31 */
}
void func1(void) {
char mystr[31]; char wrong[30];
func2(&mystr); /* OK note & not usually used for "strings" */
func2(&wrong); /* ERROR CAUGHT pointer mismatch */
}
This is effectively like classic Pascal. Except for the pointer being
explicit, as it always is in C (and the C-like part of C++).
In C++ you can use a reference instead of a pointer,
and it does require matching of the array bound;
and/or templates that deduce the size of an array
(and usually inline to a call of a generic implementation
passing the bound explicitly).
However, where you do have a (nonparameter) array declaration,
sizeof the array is exactly sizeof one element times the bound.
There may be padding within a struct or union element (and
no rep clause to control it, though _some_ compiler have
nonportable options or pragmas), but NOT between elements
or at the end of an array. And char in particular MUST
have sizeof 1 and minimal alignment.
--
- David.Thompson 1 now at worldnet.att.net
next prev parent reply other threads:[~2001-08-21 5:54 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-08-03 4:16 Ada Idioms Progress Preview James Rogers
2001-08-03 19:45 ` Robert Dewar
2001-08-03 22:02 ` James Rogers
2001-08-06 22:33 ` Stanley R. Allen
2001-08-07 2:45 ` tmoran
2001-08-07 12:15 ` Larry Kilgallen
2001-08-07 13:26 ` Philip Anderson
2001-08-08 2:23 ` Robert Dewar
2001-08-08 5:58 ` Ehud Lamm
2001-08-08 2:19 ` Robert Dewar
2001-08-08 15:13 ` Ted Dennison
2001-08-08 18:03 ` tmoran
2001-08-09 20:36 ` Florian Weimer
2001-08-10 21:02 ` Jay Nabonne
2001-08-10 21:51 ` Larry Kilgallen
2001-08-13 14:19 ` Ted Dennison
2001-08-13 14:05 ` Ted Dennison
2001-08-13 14:19 ` Marin David Condic
2001-08-13 15:47 ` Ole-Hjalmar Kristensen
2001-08-13 16:22 ` Marin David Condic
2001-08-13 18:48 ` Larry Kilgallen
2001-08-14 7:05 ` Ole-Hjalmar Kristensen
2001-08-13 20:20 ` James Rogers
2001-08-14 1:09 ` Warren W. Gay VE3WWG
2001-08-14 6:15 ` James Rogers
2001-08-14 14:03 ` Warren W. Gay VE3WWG
2001-08-21 5:54 ` David Thompson [this message]
2001-08-16 18:42 ` Jay Nabonne
2001-08-17 1:25 ` Robert Dewar
2001-08-13 21:47 ` Ted Dennison
2001-08-14 7:37 ` Ole-Hjalmar Kristensen
2001-08-14 14:59 ` Ted Dennison
2001-08-14 13:22 ` Marin David Condic
2001-08-14 15:12 ` Ted Dennison
2001-08-14 15:33 ` Marin David Condic
2001-08-14 8:49 ` Lutz Donnerhacke
2001-08-14 9:38 ` Ole-Hjalmar Kristensen
2001-08-14 9:54 ` Lutz Donnerhacke
2001-08-14 14:51 ` James Rogers
2001-08-14 16:44 ` Darren New
2001-08-14 1:39 ` Slicing ( Ada Idioms Progress Preview ) Warren W. Gay VE3WWG
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox