Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #91393 > unrolled thread

string swap

Started bysinbad <sinbad.sinbad@gmail.com>
First post2016-07-31 07:45 -0700
Last post2016-07-31 14:28 -0500
Articles 20 on this page of 21 — 14 participants

Back to article view | Back to comp.lang.c


Contents

  string swap sinbad <sinbad.sinbad@gmail.com> - 2016-07-31 07:45 -0700
    Re: string swap Melzzzzz <mel@zzzzz.com> - 2016-07-31 16:51 +0200
      Re: string swap Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2016-07-31 12:48 -0400
    Re: string swap James Kuyper <jameskuyper@verizon.net> - 2016-07-31 11:14 -0400
      Re: string swap Real Troll <real.troll@trolls.com> - 2016-07-31 15:43 -0400
        Re: string swap "James R. Kuyper" <jameskuyper@verizon.net> - 2016-08-01 12:55 -0400
          Re: string swap "James R. Kuyper" <jameskuyper@verizon.net> - 2016-08-01 15:35 -0400
            Re: string swap supercat@casperkitty.com - 2016-08-01 13:09 -0700
              Re: string swap Keith Thompson <kst-u@mib.org> - 2016-08-01 14:36 -0700
              Re: string swap jameskuyper@verizon.net - 2016-08-01 15:58 -0700
    Re: string swap raltbos@xs4all.nl (Richard Bos) - 2016-07-31 15:38 +0000
      Re: string swap Tim Rentsch <txr@alumni.caltech.edu> - 2016-07-31 12:42 -0700
        Re: string swap Randy Howard <rhoward.mx@EverybodyUsesIt.com> - 2016-07-31 18:16 -0500
          Re: string swap Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-01 07:33 -0700
        Re: string swap raltbos@xs4all.nl (Richard Bos) - 2016-08-03 13:21 +0000
          Re: string swap Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-05 09:11 -0700
            Re: string swap raltbos@xs4all.nl (Richard Bos) - 2016-08-10 12:56 +0000
              Re: string swap Tim Rentsch <txr@alumni.caltech.edu> - 2016-08-17 09:45 -0700
                Re: string swap raltbos@xs4all.nl (Richard Bos) - 2016-08-21 12:42 +0000
    Re: string swap Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-07-31 17:16 +0100
    Re: string swap Les Cargill <lcargill99@comcast.com> - 2016-07-31 14:28 -0500

Page 1 of 2  [1] 2  Next page →


#91393 — string swap

Fromsinbad <sinbad.sinbad@gmail.com>
Date2016-07-31 07:45 -0700
Subjectstring swap
Message-ID<6461d9d8-9101-47e4-a0a5-7609a32b8ec1@googlegroups.com>
why is the following piece of code crashing at "*(s + src) = *(s + dst)";
I thought this code should swap the values at locations 0 and 2 and these
indices are with in the bounds.

int
swap(char *s, int src, int dst)
{
    int tmp;

    tmp = *(s + src);
    *(s + src) = *(s + dst);
    *(s + dst) = tmp;
    return(0);
}


int
main() {
    char *s = "abc";
    swap(s, 0, 2);
    return(0);
}

[toc] | [next] | [standalone]


#91395

FromMelzzzzz <mel@zzzzz.com>
Date2016-07-31 16:51 +0200
Message-ID<20160731165141.1127cdd3@maxa-pc>
In reply to#91393
On Sun, 31 Jul 2016 07:45:44 -0700 (PDT)
sinbad <sinbad.sinbad@gmail.com> wrote:

> why is the following piece of code crashing at "*(s + src) = *(s +
> dst)"; I thought this code should swap the values at locations 0 and
> 2 and these indices are with in the bounds.
> 
> int
> swap(char *s, int src, int dst)
> {
>     int tmp;
> 
>     tmp = *(s + src);
>     *(s + src) = *(s + dst);
>     *(s + dst) = tmp;
>     return(0);
> }
> 
> 
> int
> main() {
>     char *s = "abc";
>     swap(s, 0, 2);
>     return(0);
> }

C is low level language. line `char* s = "abc";` does not allocates
string...rather it assigns pointer to first element of non
writeable string literal...

[toc] | [prev] | [next] | [standalone]


#91402

FromLew Pitcher <lew.pitcher@digitalfreehold.ca>
Date2016-07-31 12:48 -0400
Message-ID<nnla52$4j6$1@dont-email.me>
In reply to#91395
On Sunday July 31 2016 10:51, in comp.lang.c, "Melzzzzz" <mel@zzzzz.com>
wrote:

> On Sun, 31 Jul 2016 07:45:44 -0700 (PDT)
> sinbad <sinbad.sinbad@gmail.com> wrote:
> 
>> why is the following piece of code crashing at "*(s + src) = *(s +
>> dst)"; I thought this code should swap the values at locations 0 and
>> 2 and these indices are with in the bounds.
>> 
>> int
>> swap(char *s, int src, int dst)
>> {
>>     int tmp;
>> 
>>     tmp = *(s + src);
>>     *(s + src) = *(s + dst);
>>     *(s + dst) = tmp;
>>     return(0);
>> }
>> 
>> 
>> int
>> main() {
>>     char *s = "abc";
>>     swap(s, 0, 2);
>>     return(0);
>> }
> 
> C is low level language. line `char* s = "abc";` does not allocates
> string...rather it assigns pointer to first element of non
> writeable string literal...

Sinbad:

To make this (and Richard Bos) point clearer, the C language does /not/
guarantee that the contents of string literal ( the thing pointed to by <<s>>
in {char *s = "abc";} ) can be modified. In fact, the standard specifically
states that an attempt to modify a string literal (by, for instance,
replacing one element value with another) invoked "undefined behaviour".

Such behaviour can include program termination, or aberrant or inconsistant
behaviour of the program logic.

This is important, because, from this pov,
  {
    char string_array[] = "abc";
    swap(string_array, 0, 2);
  }
should (modulo the correctness of the swap() function) perform as expected,
while
  {
    char *string_pointer = "abc";
    swap(string_pointer, 0, 2);
  }
or
  {
    swap("abc", 0, 2);
  }
likely will not.

In other words, even if you get swap() to work correctly, it can still fail,
even though the parameters seem to be "type correct" (string_array passes
into the function as "pointer to character", as does string_pointer).

-- 
Lew Pitcher
"In Skills, We Trust"
PGP public key available upon request

[toc] | [prev] | [next] | [standalone]


#91396

FromJames Kuyper <jameskuyper@verizon.net>
Date2016-07-31 11:14 -0400
Message-ID<nnl4jp$gog$1@dont-email.me>
In reply to#91393
On 07/31/2016 10:45 AM, sinbad wrote:
> why is the following piece of code crashing at "*(s + src) = *(s + dst)";
> I thought this code should swap the values at locations 0 and 2 and these
> indices are with in the bounds.
> 
> int
> swap(char *s, int src, int dst)
> {
>     int tmp;
> 
>     tmp = *(s + src);
>     *(s + src) = *(s + dst);
>     *(s + dst) = tmp;
>     return(0);

I address your actual problem at the bottom of this message.
The following comments have nothing to o with your problem, they're just
general programming advice:

The parentheses around the 0 in the return statement are unnecessary,
and give the incorrect impression that return() is a function call. It
isn't, and it will cause less confusion in the long run if you make a
habit of not using them.

Your function always returns 0, which means there's no reason to bother
checking what value it returns, which in turn means there's no reason
why the function should bother returning a value. You should have
declared it as a void function, and then you wouldn't even need a return
statement.

In this very limited context, you can be quite certain that swap() will
never be called with a null pointer. However, in the general case, you
can't be sure of that, so swap should check whether s is null. If it is,
swap should skip all of the other code in the function, and return an
error code - in which case returning an 'int' value is perfectly reasonable.

> }
> 
> 
> int
> main() {
>     char *s = "abc";
>     swap(s, 0, 2);
>     return(0);
> }

"In translation phase 7, a byte or code of value zero is appended to
each multibyte character sequence that results from a string literal or
literals.78) The multibyte character sequence is then used to initialize
an array of static storage duration and length just sufficient to
contain the sequence. ..." (6.4.5p6)

The string literal itself is automatically converted into a pointer to
the first element of that array (6.3.2.1p3), which is stored in s.

"... If the program attempts to modify such an array, the behavior is
undefined." (6.4.5p7)

swap(s, 0, 2) tries to modify both the first and third elements of that
array, which is your problem. What you need to do in order for this
program to work as you desire is to create a modifiable array:

    char sarr[] = "abc";

6.3.2.1p3 has a specific exemption for the case of a string literal
being used to initialize an array. Instead of being converted into a
pointer to char (which would be a constraint violation in this context),
the array is initialized by copying from the array corresponding to
"abc". Unlike "abc", the array sarr can safely be modified.

[toc] | [prev] | [next] | [standalone]


#91420

FromReal Troll <real.troll@trolls.com>
Date2016-07-31 15:43 -0400
Message-ID<nnlkgp$1jhc$1@gioia.aioe.org>
In reply to#91396
On 31/07/2016 16:14, James Kuyper wrote:
> Your function always returns 0, which means there's no reason to 
> bother checking what value it returns, which in turn means there's no 
> reason why the function should bother returning a value. You should 
> have declared it as a void function,

so are you saying this could be wrong?

> #include <stdio.h>
>     int main(void)
>     {
>         printf("Output from running program");
>         return 0;
>     } 

It has a void but it also returns 0.  Please clarify.

thank you.

[toc] | [prev] | [next] | [standalone]


#91499

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-08-01 12:55 -0400
Message-ID<2d6cdbc5-d5a7-df68-2cbd-8a427828d2e0@verizon.net>
In reply to#91420
On 07/31/2016 03:43 PM, Real Troll wrote:
> On 31/07/2016 16:14, James Kuyper wrote:
>> Your function always returns 0, which means there's no reason to
>> bother checking what value it returns, which in turn means there's no
>> reason why the function should bother returning a value. You should
>> have declared it as a void function,
>
> so are you saying this could be wrong?

No.

>> #include <stdio.h>
>>     int main(void)
>>     {
>>         printf("Output from running program");
>>         return 0;
>>     }
>
> It has a void but it also returns 0.  Please clarify.

The only use of void in that code is in the parameter list for main(). 
In that context, it means that main() takes no arguments. I was talking 
about void as the return type of the function. main() has a return type 
of int, so returning 0 is fine.

I didn't actually say that anything was "wrong". I was saying that it 
was pointless for a function to return only a single possible value. The 
return value is a communications channel between a function and it's 
caller - and if there's only one possible value, no information is 
actually being communicated through that channel. That applies, in 
particular, to your example of main() above - but the standard does not 
give us permission to define main() as returning void.

Here's some related things that ARE wrong:

"A return statement with an expression shall not appear in a function 
whose return type is void. A return statement without an expression 
shall only appear in a function whose return type is void." (6.8.6.4) 
These are both constraints. Violating either constraint means that the 
implementation is required to issue at least one diagnostic message, and 
is permitted to reject your program for that reason. If it chooses to 
continue translation, and if you choose to execute the resulting 
program, the behavior of that program is undefined.

"If the } that terminates a function is reached, and the value of the 
function call is used by the caller, the behavior is undefined." (6.9.1p12)

[toc] | [prev] | [next] | [standalone]


#91518

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-08-01 15:35 -0400
Message-ID<b5cac7d1-762e-ca1a-dd57-33284faea2de@verizon.net>
In reply to#91499
On 08/01/2016 12:55 PM, James R. Kuyper wrote:
> On 07/31/2016 03:43 PM, Real Troll wrote:
>> On 31/07/2016 16:14, James Kuyper wrote:
>>> Your function always returns 0, which means there's no reason to
>>> bother checking what value it returns, which in turn means there's no
>>> reason why the function should bother returning a value. You should
>>> have declared it as a void function,
>>
>> so are you saying this could be wrong?
>
> No.
>
>>> #include <stdio.h>
>>>     int main(void)
>>>     {
>>>         printf("Output from running program");
>>>         return 0;
>>>     }
>>
>> It has a void but it also returns 0.  Please clarify.
...
> I didn't actually say that anything was "wrong". I was saying that it
> was pointless for a function to return only a single possible value. The
> return value is a communications channel between a function and it's
> caller - and if there's only one possible value, no information is
> actually being communicated through that channel. That applies, in
> particular, to your example of main() above - but the standard does not
> give us permission to define main() as returning void.

Let me go into that a little further. The key reason why my criticism 
does not apply to main() is that main() has two interfaces defined by 
the standard (and the standard allows an implementation to define 
additional interfaces for it). Those interfaces are shared by every 
definition of main(). It made sense for the designer of that interface 
to allow for the possibility that some of those definitions will need to 
have some method of reporting failure back to calling environment. It 
also makes sense that some definitions of main() will always return the 
same value (usually EXIT_SUCCESS or 0, but consider cases like the UNIX 
routine /bin/false). Note: in your example code, I could argue for 
"return ferror(stdout) ? EXIT_FAILURE : EXIT_SUCCESS;".

Let's consider a function that is called through a pointer, which might 
point at any one of several different functions. If the return value 
tells you something about the function called, any one of those 
functions will always return the same value, but it can still make sense 
for the caller to look at that value, because the caller doesn't know 
which of those functions is the one it called through that pointer.

The criticism I provided above only applies if you are free to define 
the interface yourself, rather than being required to match someone 
else's interface spec. Even then, if many different routines will be 
making use of the same interface, it only applies if every one of them 
will always return the same value.

[toc] | [prev] | [next] | [standalone]


#91523

Fromsupercat@casperkitty.com
Date2016-08-01 13:09 -0700
Message-ID<cf8aea31-c4ba-4ea3-ac90-bbeab637cbd0@googlegroups.com>
In reply to#91518
On Monday, August 1, 2016 at 2:35:38 PM UTC-5, James R. Kuyper wrote:
> Let's consider a function that is called through a pointer, which might 
> point at any one of several different functions. If the return value 
> tells you something about the function called, any one of those 
> functions will always return the same value, but it can still make sense 
> for the caller to look at that value, because the caller doesn't know 
> which of those functions is the one it called through that pointer.

A nasty gotcha related to that is that: falling through a non-void function
without returning a value has defined behavior if the caller doesn't do
anything with the return value, but UB if the caller doesn't "immediately"
ignore the result.  This can make wrapper design needlessly difficult.

If one wants to have a wrapper that returns a useful result in cases where
the called function returns one, and doesn't need to return a result in
cases where the called function doesn't, the same machine code should be
able to handle both cases, but the Standard doesn't define any means by
which the wrapper could avoid having to determine which case applies and
then do something like:

    if (...foo() will return value...)
      return foo(whatever);
    else
      foo(whatever);

Perhaps a compiler may be able to recognize that both function calls could
use identical machine code, and in turn recognize that there's no need to
test whether foo() is being invoked in a way that will return a value.
Such a compiler would then be able to generate code which is agnostic to
whether foo() is going to return a value, and simply gives its caller
whatever useful or garbage result came out of foo().  It seems unhelpful,
though, for a language to require a programmer to write unwanted code in
the hope that a compiler will eliminate it.

[toc] | [prev] | [next] | [standalone]


#91534

FromKeith Thompson <kst-u@mib.org>
Date2016-08-01 14:36 -0700
Message-ID<ln60rk41e7.fsf@kst-u.example.com>
In reply to#91523
supercat@casperkitty.com writes:
> On Monday, August 1, 2016 at 2:35:38 PM UTC-5, James R. Kuyper wrote:
>> Let's consider a function that is called through a pointer, which might 
>> point at any one of several different functions. If the return value 
>> tells you something about the function called, any one of those 
>> functions will always return the same value, but it can still make sense 
>> for the caller to look at that value, because the caller doesn't know 
>> which of those functions is the one it called through that pointer.
>
> A nasty gotcha related to that is that: falling through a non-void function
> without returning a value has defined behavior if the caller doesn't do
> anything with the return value, but UB if the caller doesn't "immediately"
> ignore the result.  This can make wrapper design needlessly difficult.

I don't think that's particularly nasty.  It's there to cater to
pre-ANSI code that couldn't use "void".  A function that didn't
return a meaningful value was defined with no explicit return type,
which was equivalent to returning int.  Falling off the end would
return an unspecified result which the caller was expected to ignore.

I don't know what you mean by

    doesn't "immediately" ignore the result.

UB occurs if the caller *uses* the result.

So don't do that.  If a function is defined to return a non-void type,
make sure it always returns a value of that type.  If it returns int,
add `return 0;` at the bottom.  If it returns a pointer, add `return
NULL;` at the bottom.  If you don't, at least some compilers will give
you a warning similar to "control reaches end of non-void function".

(The main function is of course a special case.)

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#91545

Fromjameskuyper@verizon.net
Date2016-08-01 15:58 -0700
Message-ID<e4cf43bc-817f-481c-889e-b624664e55f5@googlegroups.com>
In reply to#91523
On Monday, August 1, 2016 at 4:09:46 PM UTC-4, supe...@casperkitty.com wrote:
> On Monday, August 1, 2016 at 2:35:38 PM UTC-5, James R. Kuyper wrote:
> > Let's consider a function that is called through a pointer, which might 
> > point at any one of several different functions. If the return value 
> > tells you something about the function called, any one of those 
> > functions will always return the same value, but it can still make sense 
> > for the caller to look at that value, because the caller doesn't know 
> > which of those functions is the one it called through that pointer.
> 
> A nasty gotcha related to that is that: falling through a non-void function
> without returning a value has defined behavior if the caller doesn't do
> anything with the return value, but UB if the caller doesn't "immediately"
> ignore the result.  This can make wrapper design needlessly difficult.
> 
> If one wants to have a wrapper that returns a useful result in cases where
> the called function returns one, and doesn't need to return a result in
> cases where the called function doesn't, the same machine code should be
> able to handle both cases, but the Standard doesn't define any means by
> which the wrapper could avoid having to determine which case applies and
> then do something like:
> 
>     if (...foo() will return value...)
>       return foo(whatever);
>     else
>       foo(whatever);
>
> Perhaps a compiler may be able to recognize that both function calls could
> use identical machine code, and in turn recognize that there's no need to
> test whether foo() is being invoked in a way that will return a value.
> Such a compiler would then be able to generate code which is agnostic to
> whether foo() is going to return a value, and simply gives its caller
> whatever useful or garbage result came out of foo().  It seems unhelpful,

Why in the world would you want to propagate garbage? A desire to spread garbage values around seems to underlay most of your objections to C. In order to avoid dealing with that garbage, the wrapper's caller would also have to know under what conditions foo() will fail to return a value:

    if(foo will return a value)
       x = foo_wrapper(whatever);
    else
    {
       foo_wrapper(whatever);
       x = NO_FOO_VALUE;
    }

Personally, I'd prefer to do something like that in foo_wrapper() itself, rather than in foo_wrapper's caller. Even better would be to do it inside of foo().
However, if you want to propagate garbage, there's a perfectly good way to do it:

void foo(int whatever, int *return_value)
{
    if(foo will return a value)
        *return_value = desired_value;
}

void foo_wrapper(int whatever, int *return_value)
{
    foo(whatever, return_value);
}

Whatever return_value points at is left completely unchanged if foo decides not to set it. foo_wrapper()'s caller can do whatever it wants to with that return value.

> though, for a language to require a programmer to write unwanted code in
> the hope that a compiler will eliminate it.

I don't see any need for my alternative above to rely upon removal of unwanted code.

[toc] | [prev] | [next] | [standalone]


#91397

Fromraltbos@xs4all.nl (Richard Bos)
Date2016-07-31 15:38 +0000
Message-ID<579e1b3a.12190156@news.xs4all.nl>
In reply to#91393
sinbad <sinbad.sinbad@gmail.com> wrote:

> int
> main() {

This is, IMAO, a horrible style. But that as an aside.

>     char *s = "abc";
>     swap(s, 0, 2);
>     return(0);
> }

Apart from what James told you, this is in fact a FAQ:
<http://c-faq.com/decl/strlitinit.html>.
You might find the rest of that site enlightening, as well.

Richard

[toc] | [prev] | [next] | [standalone]


#91419

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-07-31 12:42 -0700
Message-ID<kfneg69mw6p.fsf@x-alumni2.alumni.caltech.edu>
In reply to#91397
raltbos@xs4all.nl (Richard Bos) writes:

> sinbad <sinbad.sinbad@gmail.com> wrote:
>
>> int
>> main() {
>
> This is, IMAO, a horrible style.  [...]

That is an interesting remark.  Can you say what you
don't like about it?

[toc] | [prev] | [next] | [standalone]


#91441

FromRandy Howard <rhoward.mx@EverybodyUsesIt.com>
Date2016-07-31 18:16 -0500
Message-ID<nnm0sp$5kv$1@gioia.aioe.org>
In reply to#91419
On 7/31/16 2:42 PM, Tim Rentsch wrote:
> raltbos@xs4all.nl (Richard Bos) writes:
>
>> sinbad <sinbad.sinbad@gmail.com> wrote:
>>
>>> int
>>> main() {
>>
>> This is, IMAO, a horrible style.  [...]
>
> That is an interesting remark.  Can you say what you
> don't like about it?
>

People that use editors with good regex search like the
newline between the return type and function name, so
you can do /^funcname to jump to it quickly.  Or did you
mean main() without a void?


-- 
Randy Howard
(replace the obvious text in the obvious way if you wish to contact me 
directly)

[toc] | [prev] | [next] | [standalone]


#91481

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-08-01 07:33 -0700
Message-ID<kfny44gk18u.fsf@x-alumni2.alumni.caltech.edu>
In reply to#91441
Randy Howard <rhoward.mx@EverybodyUsesIt.com> writes:

> On 7/31/16 2:42 PM, Tim Rentsch wrote:
>> raltbos@xs4all.nl (Richard Bos) writes:
>>
>>> sinbad <sinbad.sinbad@gmail.com> wrote:
>>>
>>>> int
>>>> main() {
>>>
>>> This is, IMAO, a horrible style.  [...]
>>
>> That is an interesting remark.  Can you say what you
>> don't like about it?
>
> People that use editors with good regex search like the
> newline between the return type and function name, so
> you can do /^funcname to jump to it quickly.  Or did you
> mean main() without a void?

Well I didn't mean anything.  I was asking Richard what
things about it he doesn't like.  And of course I am
also curious to know why he finds those things (whatever
they might be) objectionable.

[toc] | [prev] | [next] | [standalone]


#91601

Fromraltbos@xs4all.nl (Richard Bos)
Date2016-08-03 13:21 +0000
Message-ID<57a1ee2d.6553343@news.xs4all.nl>
In reply to#91419
Tim Rentsch <txr@alumni.caltech.edu> wrote:

> raltbos@xs4all.nl (Richard Bos) writes:
> 
> > sinbad <sinbad.sinbad@gmail.com> wrote:
> >
> >> int
> >> main() {
> >
> > This is, IMAO, a horrible style.  [...]
> 
> That is an interesting remark.  Can you say what you
> don't like about it?

You don't write your own name

Tim
Rentsch

do you?

It's a sop to diehards who are so wedded to their refusal to use a
decent IDE with proper, project-wide search features that they can't
believe anything could be stronger than eMacs and/or Vile regexes, and
would rather mutilate their source code than switch to a more modern
development system, or even a real editor. It costs an extra line, and
splits a declaration unnecessarily, just because some people are
convinced they look like Ye Olde Time Hackeres when they use an
outdated, over-complicated, under-powered search tool.

I'll note that not even the people who advocate the above style take it
so far as to write

int
cx,
cy,
dx,
dy;

even though all their arguments apply just as much to object identifiers
as to function ones.

Richard

[toc] | [prev] | [next] | [standalone]


#91739

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-08-05 09:11 -0700
Message-ID<kfn60rfi4ao.fsf@x-alumni2.alumni.caltech.edu>
In reply to#91601
raltbos@xs4all.nl (Richard Bos) writes:

> Tim Rentsch <txr@alumni.caltech.edu> wrote:
>
>> raltbos@xs4all.nl (Richard Bos) writes:
>>
>>> sinbad <sinbad.sinbad@gmail.com> wrote:
>>>
>>>> int
>>>> main() {
>>>
>>> This is, IMAO, a horrible style.  [...]
>>
>> That is an interesting remark.  Can you say what you
>> don't like about it?
>
> You don't write your own name
>
> Tim
> Rentsch
>
> do you?
>
> It's a sop to diehards who are so wedded to their refusal to use a
> decent IDE with proper, project-wide search features that they can't
> believe anything could be stronger than eMacs and/or Vile regexes, and
> would rather mutilate their source code than switch to a more modern
> development system, or even a real editor.  It costs an extra line, and
> splits a declaration unnecessarily, just because some people are
> convinced they look like Ye Olde Time Hackeres when they use an
> outdated, over-complicated, under-powered search tool.
>
> I'll note that not even the people who advocate the above style take it
> so far as to write
>
> int
> cx,
> cy,
> dx,
> dy;
>
> even though all their arguments apply just as much to object identifiers
> as to function ones.

Let me make sure I understand what you're saying.  Your
objections are these:  that the text could be written on one line
but is instead written on two;  and that the reasons you imagine
people have for making this layout choice are stupid.  Is that a
fair summary of your comments?  Or is there something I'm
missing?

[toc] | [prev] | [next] | [standalone]


#92060

Fromraltbos@xs4all.nl (Richard Bos)
Date2016-08-10 12:56 +0000
Message-ID<57ab23ec.7710156@news.xs4all.nl>
In reply to#91739
Tim Rentsch <txr@alumni.caltech.edu> wrote:

> raltbos@xs4all.nl (Richard Bos) writes:

> > I'll note that not even the people who advocate the above style take it
> > so far as to write
> >
> > int
> > cx,
> > cy,
> > dx,
> > dy;
> >
> > even though all their arguments apply just as much to object identifiers
> > as to function ones.
> 
> Let me make sure I understand what you're saying.  Your
> objections are these:  that the text could be written on one line
> but is instead written on two;  and that the reasons you imagine
> people have for making this layout choice are stupid.  Is that a
> fair summary of your comments?

It's a rather simplistic, petty summary of my comments. I'd put it more
like this: that text which semantically belongs together is graphically
split _for no good reason_; and that the reason most often given makes
its adherents sound backward-looking rather than expert.

Richard

[toc] | [prev] | [next] | [standalone]


#92385

FromTim Rentsch <txr@alumni.caltech.edu>
Date2016-08-17 09:45 -0700
Message-ID<kfnh9ajfiof.fsf@x-alumni2.alumni.caltech.edu>
In reply to#92060
raltbos@xs4all.nl (Richard Bos) writes:

> Tim Rentsch <txr@alumni.caltech.edu> wrote:
>
>> raltbos@xs4all.nl (Richard Bos) writes:
>>
>>> [snipped portion include below]
>>
>> Let me make sure I understand what you're saying.  Your
>> objections are these:  that the text could be written on one line
>> but is instead written on two;  and that the reasons you imagine
>> people have for making this layout choice are stupid.  Is that a
>> fair summary of your comments?
>
> It's a rather simplistic, petty summary of my comments.

I'm not sure it was an unfair summary, but the tone was rather
snotty, and I apologize for that.  I should have waited longer
before replying.  Let me try now to return to substance and take
up your comments in a more constructive way.  First here is
what was said in your first response.  (Some parts reordered.)

>>> sinbad <sinbad.sinbad@gmail.com> wrote:
>>>
>>>> int
>>>> main() {
>>>
>>> This is, IMAO, a horrible style.  [...]
>>
>> That is an interesting remark.  Can you say what you
>> don't like about it?
>
> You don't write your own name
> 
> Tim
> Rentsch
> 
> do you?

I don't, but I also don't see any reason to consider the two
cases analogous.  The suggested comparison isn't even two
fruits, let alone apples-and-apples.  If we're going to look
at strained analogies, ISTM a closer match would be to a
street address:

    1600 Pennsylvania Ave
    Miami Beach, FL 33139

The two parts are semantically related, but written on separate
lines because there is an important distinction between them.
This is still not a compelling argument, because the analogy is
still strained, but it's less strained than the previous one.

> I'll note that not even the people who advocate the above style
> take it so far as to write
> 
> int
> cx,
> cy,
> dx,
> dy;
> 
> even though all their arguments apply just as much to object
> identifiers as to function ones.

A devious argument.  It sneakily implies those who write function
definitions as sinbad did will fall into Emerson's trap ("a
foolish consistency is the hobgoblin of little minds"), and then
it takes them to task for not doing so!  Furthermore it assumes
you know what all their reasons are.  Obviously some reasons might
distinguish the two cases, for the simple reason that objects and
functions are different.  What if one of the reasons for writing
function definitions with the function name on a second line is to
make them look different from object declarations/definitions?
Having that difference be more visually obvious clearly provides
some benefit.  Whether or not you think that benefit suffices to
overcome some other objections, it certainly invalidates the
object declaration style argument.
 
> It's a sop to diehards who are so wedded to their refusal to use a
> decent IDE with proper, project-wide search features that they can't
> believe anything could be stronger than eMacs and/or Vile regexes, and
> would rather mutilate their source code than switch to a more modern
> development system, or even a real editor.  It costs an extra line, and
> splits a declaration unnecessarily, just because some people are
> convinced they look like Ye Olde Time Hackeres when they use an
> outdated, over-complicated, under-powered search tool.

There are several different points raised.  Let me address them
in turn.

First: re costing an extra line.  Writing the start of a function
definition like this

    int
    main() {

takes one more line than writing it like this

    int main() {

However, when the return type and declarator are on the same
line, it is more common to see it written like this

    int main()
    {

which is the same number of lines as the first layout.  Do you
object to the "extra line" taken in that case?  If the rest of
the code follows the layout style of putting { on the same line
as if()'s, whiles(), etc (which in fact is what I observe in most
of the open source C code I've looked at), it would seem more
consistent to do that also for function definitions.  But for the
sake of argument let's assume the code layout would otherwise be
in the single-line (ie, second case above) style.  Even then, the
cost of the "extra lines" is small:  looking at roughly a dozen
open source projects, the average is about 2.3% for the .c files
(.h files are mostly not affected, so I didn't look at them).  Is
that cost worth the benefits?  Depends on what one thinks the
benefits are.  Remember also that this cost occurs only under the
assumption that the layout chosen would otherwise be in the
single-line-including-open-brace style, which IME it almost never
is.

Second: splitting a declaration unnecessarily.  I deal with this
point below.

Third: relationship to choice of editor/DE (eg, emacs/vi versus
IDE).  These comments rest on several implicit assumptions that
are not true or not always true.

Assumption 1:  Editor preference is the primary driver for
choosing to put a function's return type on a separate line.
This is certainly not always true.  In fact it is probably not
even usually true - although there may be some people for whom
this factor is the primary driver, I see no reason or evidence to
suggest that it is for most of them.

Assumption 2:  Editors like emacs or vi don't have good project
wide search functionality.  Emacs certainly does, and I suspect
vi does also.

Assumption 3:  People who prefer editors like emacs or vi do so
out of stubborness or unwillingness to change rather than making
a considered decision.  Undoubtedly this is true in some cases,
but certainly not all.

Assumption 4:  That program style should never be evaluated with
regard to what tools are (or will be) available to help program
development.  This is obviously not true.  Of course we might
choose not to adopt some proposed style rule, perhaps motivated
by a tool that might (or might not) be used, but that depends on
what one considers the costs and benefits to be, and their
respective weights, for the different options.  Decisions about
style are not made in a vacuum;  what tools are expected to be
available certainly can influence those choices.  And that is
just as true for "high powered" tools like IDEs as it is for
simpler tools like awk, grep, sed, and shell scripts.

> I'd put it more
> like this:  that text which semantically belongs together is graphically
> split _for no good reason_;  and that the reason most often given makes
> its adherents sound backward-looking rather than expert.

There are two main aspects here:  the idea that the return type
and the function declarator "belong together", and what reason(s)
there may (or may not) be for splitting them.  I will take these
one at a time, in that order.

Re: belonging together.  Some people think that, eg, an if()
statement with a single controlled statement in its body (and
no else clause) should be written like this:

    if(some-condition)
    { statement-goes-here; }

This layout style choice is sometimes motivated by the idea that
this way of writing it is more in keeping with the syntax of the
language.

ISTM that you are offering basically the same kind of argument
when you say the first part of a declaration (eg, the return type
of a function definition), and a (or the) subsequent declarator,
"semantically belong together".  At least I don't see any
significant difference between the reasoning underlying the two
viewpoints.  Do you agree with that?  If you don't, can you
explain what you think the difference is?

Assuming you agree, what I think you're saying is that how you
conceptualize the declaration requires the two parts to be
together.  In other words splitting them seems wrong because it
injures your mental model.  There isn't anything absolute in
either viewpoint, which boil down to personal perception.  Again,
is this statement one you agree with, or if not can you say why?

If all you're saying is that splitting off the return type
violates how you think the code should look, then I can accept
that just as it is - a statement of personal opinion, and nothing
more.  If you are trying to say something more than that, I don't
yet know what it is.

Second point - reasons.  You use this phrase "the reason most
often given".  I don't know what reason that would be, and I
didn't see you state it anywhere.  Did you assume I knew what
this was?  I don't.

What is more important is the idea that there is "no good reason"
for adopting a style where return types are written on separate
lines.  I don't see how you can say that.  Are you assuming you
know what all the possible reasons might be?  Or do you mean to
say just that there are no good reasons that you know of?  I am
at a loss to know which of those you meant, or if you may even
have meant something else entirely.  Can you shed some light on
that?

[toc] | [prev] | [next] | [standalone]


#92563

Fromraltbos@xs4all.nl (Richard Bos)
Date2016-08-21 12:42 +0000
Message-ID<57b9a129.11363484@news.xs4all.nl>
In reply to#92385
Tim Rentsch <txr@alumni.caltech.edu> wrote:

> Can you shed some light on that?

No, except by saying that you're taking this way too seriously and
thinking it through in far too much /hineininterpretiertes/ detail.

Richard

[toc] | [prev] | [next] | [standalone]


#91400

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-07-31 17:16 +0100
Message-ID<87h9b5wzop.fsf@bsb.me.uk>
In reply to#91393
sinbad <sinbad.sinbad@gmail.com> writes:

Just an extra note...

> int
> swap(char *s, int src, int dst)
> {
>     int tmp;
>
>     tmp = *(s + src);
>     *(s + src) = *(s + dst);
>     *(s + dst) = tmp;

*(s + src) is the same as s[src] and I don't see any advantage in
avoiding the more obvious subscript notation here.

Also, it's probably more idiomatic to pass two pointers rather than one
pointer and two indexes, but that raises the whole question of what this
function is really for.

>     return(0);
> }

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web