Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #112706 > unrolled thread
| Started by | DFS <nospam@dfs.com> |
|---|---|
| First post | 2017-06-20 12:48 -0400 |
| Last post | 2017-06-21 15:10 +0100 |
| Articles | 19 on this page of 39 — 10 participants |
Back to article view | Back to comp.lang.c
Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 12:48 -0400
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-20 18:08 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-21 09:32 -0400
Re: Warning: assignment from incompatible pointer type scott@slp53.sl.home (Scott Lurndal) - 2017-06-21 13:48 +0000
Re: Warning: assignment from incompatible pointer type Richard Heathfield <rjh@cpax.org.uk> - 2017-06-20 18:15 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 18:00 -0400
Re: Warning: assignment from incompatible pointer type "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 18:47 -0400
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-21 00:10 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 19:56 -0400
Re: Warning: assignment from incompatible pointer type "James R. Kuyper" <jameskuyper@verizon.net> - 2017-06-20 13:23 -0400
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 18:59 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-20 19:23 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 18:59 -0400
Re: Warning: assignment from incompatible pointer type Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2017-06-20 19:46 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-21 02:05 +0100
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-20 21:37 -0400
Re: Warning: assignment from incompatible pointer type Richard Heathfield <rjh@cpax.org.uk> - 2017-06-21 09:25 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-21 13:35 +0200
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-21 22:30 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-22 11:03 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 11:10 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 11:42 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-22 13:49 +0200
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 14:40 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 17:00 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-22 20:08 +0200
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-22 15:46 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-22 14:00 +0100
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 14:38 +0100
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-22 17:26 +0100
Re: Warning: assignment from incompatible pointer type Keith Thompson <kst-u@mib.org> - 2017-06-22 10:21 -0700
Re: Warning: assignment from incompatible pointer type bartc <bc@freeuk.com> - 2017-06-22 18:26 +0100
Re: Warning: assignment from incompatible pointer type David Brown <david.brown@hesbynett.no> - 2017-06-22 20:41 +0200
Re: Warning: assignment from incompatible pointer type Richard Heathfield <rjh@cpax.org.uk> - 2017-06-22 19:59 +0100
Re: Warning: assignment from incompatible pointer type Keith Thompson <kst-u@mib.org> - 2017-06-22 12:28 -0700
Re: Warning: assignment from incompatible pointer type Jerry Stuckle <jstucklex@attglobal.net> - 2017-06-21 09:49 -0400
Re: Warning: assignment from incompatible pointer type DFS <nospam@dfs.com> - 2017-06-21 10:36 -0400
Re: Warning: assignment from incompatible pointer type Jerry Stuckle <jstucklex@attglobal.net> - 2017-06-21 14:15 -0400
Re: Warning: assignment from incompatible pointer type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-06-21 15:10 +0100
Page 2 of 2 — ← Prev page 1 [2]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-22 11:10 +0100 |
| Message-ID | <lIM2B.59754$OJ2.17773@fx37.am4> |
| In reply to | #112819 |
On 22/06/2017 03:30, DFS wrote:
> On 6/21/2017 7:35 AM, David Brown wrote:
>> The speed of a program comes from many things. The algorithm used is
>> often more important than the language, and the speed of the tool's
>> libraries can be a big effect. Python excels at string handling,
>> searching and sorting - in some cases a few lines of Python code will
>> run faster than a C program for the job.
People who write Python seem to take delight in writing as
incomprehensible code as possible. That's the impression I get from
browsing comp.lang.python.
So no Python program is worth the name unless bristling with class
hierarchies, decorators and one-liners. It's one of those languages that
is written horizontally as well as vertically.
> But python is easy to learn, and has a big bunch of libraries. And I
> love the python list comprehension.
>
> One line to count the unique characters in a string.
>
> msg = "Now is the time for all good men to come to the aid of their
> country"
> for t in sorted(set([(x,msg.count(x)) for x in msg])):
> print t[0],t[1]
One-liners are not always good. This is a mild example of what I mention
above.
One-liners are hard to read (possibly hard to write too but I've never
tried!). Here, you have to prise apart what is happening, and when you
do you discover how inefficient it is.
Start with msg = "AAAAAA"
Here, msg.count(S) returns the number of times string S occurs in msg
(non-overlapping, so that "AAA".count("AA") returns 1 not 2).
The purpose of the list-comp is to end up with a list of pairs of each
character from the string, and its count. So for "AAAAAA", it will return:
[("A",6),
("A",6),
("A",6),
("A",6),
("A",6),
("A",6)]
This is where set() comes in, in eliminating such duplicates, to end up
with:
[("A",6)]
So you've done all that work, only to throw most of it away!
The sorted() bit, just appears to sort on the first element of each
tuple, so that the results are presented in alphabetical order, rather
than by count (and it's mixed up when there is mixed case).
That it works seems to be all that is important to Python programmers.
So a language that is inherently slow is even slower by encouraging lazy
coding.
One advantage of a language like C is that it forces you to work more
efficiently. Here's the same task in C:
#include <stdio.h>
int main(void) {
char* msg = "Now is the time for all good men"
" to come to the aid of their country";
char* s;
int counts[256]={0};
int c;
s=msg;
while (c=*s++) ++counts[c];
for (c=' '; c<256; ++c)
if (counts[c]) printf("'%c': %d\n",c,counts[c]);
}
And, surprisingly, the actual work of creating the histogram is also a
one-liner! But a simpler one, that is easier to understand. The rest is
just printing the results or declaring names.
I would wager that it is considerably faster than the Python too, even
if most of the underlying code to implement list-comps, construct
tuples, .count, set() and sorted() is in C.
(Maybe I'll try it later on a much longer string.)
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-22 11:42 +0100 |
| Message-ID | <MaN2B.26007$3y7.25178@fx35.am4> |
| In reply to | #112826 |
On 22/06/2017 11:10, bartc wrote: > On 22/06/2017 03:30, DFS wrote: >> msg = "Now is the time for all good men to come to the aid of their >> country" >> for t in sorted(set([(x,msg.count(x)) for x in msg])): >> print t[0],t[1] > I would wager that it is considerably faster than the Python too, even > if most of the underlying code to implement list-comps, construct > tuples, .count, set() and sorted() is in C. > > (Maybe I'll try it later on a much longer string.) Yes, the code as you have it is very poor. Using a test string 1000 times longer, Python took 10 seconds, C pretty much 0 seconds. Using a test string 1000000 times longer (68MB), then I estimate your Python one-liner would take about 3 months. But Ben's version was around 3.6 seconds (rather apt as it was Python 3.6). The C version was 0.26 seconds, using my own poor compiler; I had to drag out gcc-O3 to reduce it to 0.16 seconds. About what you might expect, compared with reasonable Python code, but where most of the work is internal (so is probably executing C). (Pypy had some trouble with this as it took 10 seconds. In all versions, the cost of constructing the big string was insignificant.) -- bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-22 13:49 +0200 |
| Message-ID | <oigalp$lg8$1@dont-email.me> |
| In reply to | #112827 |
On 22/06/17 12:42, bartc wrote: > On 22/06/2017 11:10, bartc wrote: >> On 22/06/2017 03:30, DFS wrote: > >>> msg = "Now is the time for all good men to come to the aid of their >>> country" >>> for t in sorted(set([(x,msg.count(x)) for x in msg])): >>> print t[0],t[1] > >> I would wager that it is considerably faster than the Python too, even >> if most of the underlying code to implement list-comps, construct >> tuples, .count, set() and sorted() is in C. >> >> (Maybe I'll try it later on a much longer string.) > > Yes, the code as you have it is very poor. Using a test string 1000 > times longer, Python took 10 seconds, C pretty much 0 seconds. On my testing (with old Python 2.7), using a 1000 times longer string took 7 seconds. But using an appropriate Python algorithm it was 50 ms. Using a 1,000,000 times longer string took 34 seconds. That is still a good deal longer than the C version, but not bad at all - the scaling is approximately linear. And the code is >>> from collections import Counter >> msg = "Now is the time for all good men to come to the aid of their country" >>> m = msg * 1000000 >>> print(sorted(Counter(m).items())) The Pythonic way is "Find the right tool in the standard library. Use it to do the job - it will be faster than using hand-made methods". Testing on a faster computer with msg * 1000000: python 2.7 : 9.7 seconds python 3.5 : 2.1 seconds C : 0.1 seconds. pypy : 1.2 seconds So we see that the Python version takes just a couple of lines of clear code (when written well), and is 20 times slower than C. With modern JIT, it is 10 times slower. This is with a task that is well suited to C, and does not play to Python's strengths. > > Using a test string 1000000 times longer (68MB), then I estimate your > Python one-liner would take about 3 months. > > But Ben's version was around 3.6 seconds (rather apt as it was Python 3.6). > > The C version was 0.26 seconds, using my own poor compiler; I had to > drag out gcc-O3 to reduce it to 0.16 seconds. About what you might > expect, compared with reasonable Python code, but where most of the work > is internal (so is probably executing C). > > (Pypy had some trouble with this as it took 10 seconds. In all versions, > the cost of constructing the big string was insignificant.) > The task of constructing the big string can be very significant in C if you use a simple strcat loop!
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-22 14:40 +0100 |
| Message-ID | <lNP2B.31164$9u1.1234@fx06.am4> |
| In reply to | #112828 |
On 22/06/2017 12:49, David Brown wrote: > On 22/06/17 12:42, bartc wrote: >> (Pypy had some trouble with this as it took 10 seconds. In all versions, >> the cost of constructing the big string was insignificant.) >> > > The task of constructing the big string can be very significant in C if > you use a simple strcat loop! Yeah... I had to switch over to memcpy as strcat was exhibiting similar n-squared behaviour to the OP's original Python. -- bartc
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-22 17:00 +0100 |
| Message-ID | <aQR2B.15044$dH.11239@fx17.am4> |
| In reply to | #112828 |
On 22/06/2017 12:49, David Brown wrote:
> On 22/06/17 12:42, bartc wrote:
>>>> from collections import Counter
>>> msg = "Now is the time for all good men to come to the aid of their
> country"
>>>> m = msg * 1000000
>>>> print(sorted(Counter(m).items()))
>
> The Pythonic way is "Find the right tool in the standard library. Use
> it to do the job - it will be faster than using hand-made methods".
>
> Testing on a faster computer with msg * 1000000:
>
> python 2.7 : 9.7 seconds
> python 3.5 : 2.1 seconds
> C : 0.1 seconds.
>
> pypy : 1.2 seconds
>
> So we see that the Python version takes just a couple of lines of clear
> code (when written well),
I don't agree it is clear. The original required knowledge of .count(),
set(), and sorted(); this further needs .items() and Counter().
This is not really programming either. (You might as well write C code
consisting of sequences of system() calls. That might well invoke a
Python program.)
And when I tried it, I got about 5 seconds on Py3, and 3.5 seconds on Pypy.
This is the C algorithm expressed in Python:
def gethist(s):
counts=[0,]*256
for c in s:
counts[ord(c)]+=1
return counts
and is called like this:
counts=gethist(msg)
for i in range(32,256):
if counts[i]:
print (chr(i),counts[i])
This version takes 12 seconds in Py3, but now allows pypy to do its
thing with loops; pypy takes only 0.6 seconds, comparing much more
closely with C.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-22 20:08 +0200 |
| Message-ID | <oih0sr$2vg$1@dont-email.me> |
| In reply to | #112833 |
On 22/06/17 18:00, bartc wrote: > On 22/06/2017 12:49, David Brown wrote: >> On 22/06/17 12:42, bartc wrote: > >>>>> from collections import Counter >>>> msg = "Now is the time for all good men to come to the aid of their >> country" >>>>> m = msg * 1000000 >>>>> print(sorted(Counter(m).items())) >> >> The Pythonic way is "Find the right tool in the standard library. Use >> it to do the job - it will be faster than using hand-made methods". >> >> Testing on a faster computer with msg * 1000000: >> >> python 2.7 : 9.7 seconds >> python 3.5 : 2.1 seconds >> C : 0.1 seconds. >> >> pypy : 1.2 seconds >> >> So we see that the Python version takes just a couple of lines of clear >> code (when written well), > > I don't agree it is clear. The original required knowledge of .count(), > set(), and sorted(); this further needs .items() and Counter(). I think it is reasonable to expect a basic knowledge of Python here. If you have used Python, you know what ".items()" does. You might not have known of the "Counter" container type before - clearly DFS didn't or he would have used it. But when you see "from collections import Counter" you can tell very quickly that it is a type of collection class, and its use is rather obvious from its name. And as for "sorted" - if you can't guess what that does, you might want to start with some basic English lessons. This is "clear code" because it is easy to read and understand. I expect pretty much everyone in this group - even with no Python experience - to have a reasonable understanding of what it does. You have to know a bit of Python in order to be able to /write/ the code, but not to understand it. > > This is not really programming either. (You might as well write C code > consisting of sequences of system() calls. That might well invoke a > Python program.) Of course it is programming! > > And when I tried it, I got about 5 seconds on Py3, and 3.5 seconds on Pypy. > > This is the C algorithm expressed in Python: > > def gethist(s): > counts=[0,]*256 > for c in s: > counts[ord(c)]+=1 > return counts > > and is called like this: > > counts=gethist(msg) > for i in range(32,256): > if counts[i]: > print (chr(i),counts[i]) > > This version takes 12 seconds in Py3, but now allows pypy to do its > thing with loops; pypy takes only 0.6 seconds, comparing much more > closely with C. > Now /that/ is an interesting result. It is not the Pythonic way to write it, but I guess pypy can do a better job with such code. For me, Python 3 gives 4.7 seconds here and pypy takes 0.3 seconds. It is even closer to the C if the message is stored as a Python3 "bytes" object, rather than a string, and that pulls the Python 3 time down to 3.2 seconds for me. But pypy does not (currently) support "bytes". For optimal Python code, the next step would be numpy (or numpypy for pypy). But that is getting /way/ off-topic for here. The point of my comments is that C is not necessarily faster than Python - Python code with a good algorithm and good implementation of the algorithm can be faster than C code with a weak algorithm, and because Python makes it much quicker and simpler to write some kinds of code, it can be a faster solution overall.
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-22 15:46 -0400 |
| Message-ID | <oih6jp$m2n$2@dont-email.me> |
| In reply to | #112844 |
On 6/22/2017 2:08 PM, David Brown wrote:
> You might not have known of the "Counter" container type before - clearly DFS didn't or he
> would have used it.
I do know about the Counter class and have used it for counting words.
from __future__ import division
import sys, os, string, time
from collections import Counter
start=time.clock()
infile,topn=sys.argv[1],int(sys.argv[2])
with open(infile,'r') as f:
chars=f.read().lower()
chars=chars.translate(None,string.digits)
chars=chars.translate(None,string.punctuation)
wordlist=chars.split()
print "File: ",os.path.getsize(infile),"bytes"
print "Words:",len(wordlist)
print
i,topcount=1,0
for word,count in Counter(wordlist).most_common(topn):
print str(i)+'.',count,word
i+=1;topcount+=count
print
j=str(int(round(100*(topcount/(len(wordlist))))))+'%'
print 'The top %d words account for %s of all words in %s' % (topn,j,infile)
print '%.3gs'%(time.clock()-start)
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-22 14:00 +0100 |
| Message-ID | <87k24489ep.fsf@bsb.me.uk> |
| In reply to | #112826 |
bartc <bc@freeuk.com> writes:
> On 22/06/2017 03:30, DFS wrote:
<snip>
>> But python is easy to learn, and has a big bunch of libraries. And I
>> love the python list comprehension.
>>
>> One line to count the unique characters in a string.
>>
>> msg = "Now is the time for all good men to come to the aid of their country"
>> for t in sorted(set([(x,msg.count(x)) for x in msg])):
>> print t[0],t[1]
<snip>
> One advantage of a language like C is that it forces you to work more
> efficiently. Here's the same task in C:
No the C you show is for slightly a different task, but it's different
in a way that matters to how good C is at doing it. Python (at least
modern Python) is Unicode-aware actual letters are counted, not just
bytes. I'm sure the C code for the same task would still beat Python
hands down, but it would require a little more fiddling about.
> #include <stdio.h>
>
> int main(void) {
>
> char* msg = "Now is the time for all good men"
> " to come to the aid of their country";
> char* s;
> int counts[256]={0};
> int c;
>
> s=msg;
>
> while (c=*s++) ++counts[c];
>
> for (c=' '; c<256; ++c)
> if (counts[c]) printf("'%c': %d\n",c,counts[c]);
> }
You allocate space for 256 byte counts but char might be signed. This
is another example of where script languages win over C -- usually fewer
bugs in corner cases.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-22 14:38 +0100 |
| Message-ID | <uLP2B.31163$9u1.10034@fx06.am4> |
| In reply to | #112829 |
On 22/06/2017 14:00, Ben Bacarisse wrote:
> bartc <bc@freeuk.com> writes:
>
>> On 22/06/2017 03:30, DFS wrote:
> <snip>
>>> But python is easy to learn, and has a big bunch of libraries. And I
>>> love the python list comprehension.
>>>
>>> One line to count the unique characters in a string.
>>>
>>> msg = "Now is the time for all good men to come to the aid of their country"
>>> for t in sorted(set([(x,msg.count(x)) for x in msg])):
>>> print t[0],t[1]
>
> <snip>
>> One advantage of a language like C is that it forces you to work more
>> efficiently. Here's the same task in C:
>
> No the C you show is for slightly a different task, but it's different
> in a way that matters to how good C is at doing it. Python (at least
> modern Python) is Unicode-aware actual letters are counted, not just
> bytes. I'm sure the C code for the same task would still beat Python
> hands down, but it would require a little more fiddling about.
So the C also requires you to make decisions about how in-depth a
solution needs to be. If that information is available, then again you
can choose a more efficient solution. Such as working only with 8-bit
characters, or with 7-bit ASCII.
(With a string representing UTF8, then the ASCII counts are represented
properly, but the rest is just the meaningless counts of the codes 128
to 255 used to represent other Unicode characters via multi-byte sequences.)
>> #include <stdio.h>
>>
>> int main(void) {
>>
>> char* msg = "Now is the time for all good men"
>> " to come to the aid of their country";
>> char* s;
>> int counts[256]={0};
>> int c;
>>
>> s=msg;
>>
>> while (c=*s++) ++counts[c];
>>
>> for (c=' '; c<256; ++c)
>> if (counts[c]) printf("'%c': %d\n",c,counts[c]);
>> }
>
> You allocate space for 256 byte counts but char might be signed. This
> is another example of where script languages win over C -- usually fewer
> bugs in corner cases.
This is just the result of silly decision in C to make char signed.
And all compilers I've just tested make it signed, with default options.
(But FWIW, I was testing with my own compiler where char is unsigned.)
You would expect thorough testing however to pick up things like this.
Especially if you first develop in the scripting language - using
techniques not too different from what is available in the low level one
- then port the algorithm across and compare results.
--
bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-22 17:26 +0100 |
| Message-ID | <87efuc7zvj.fsf@bsb.me.uk> |
| In reply to | #112830 |
bartc <bc@freeuk.com> writes:
> On 22/06/2017 14:00, Ben Bacarisse wrote:
>> bartc <bc@freeuk.com> writes:
>>
>>> On 22/06/2017 03:30, DFS wrote:
>> <snip>
>>>> But python is easy to learn, and has a big bunch of libraries. And I
>>>> love the python list comprehension.
>>>>
>>>> One line to count the unique characters in a string.
>>>>
>>>> msg = "Now is the time for all good men to come to the aid of their country"
>>>> for t in sorted(set([(x,msg.count(x)) for x in msg])):
>>>> print t[0],t[1]
>>
>> <snip>
>>> One advantage of a language like C is that it forces you to work more
>>> efficiently. Here's the same task in C:
>>
>> No the C you show is for slightly a different task, but it's different
>> in a way that matters to how good C is at doing it. Python (at least
>> modern Python) is Unicode-aware actual letters are counted, not just
>> bytes. I'm sure the C code for the same task would still beat Python
>> hands down, but it would require a little more fiddling about.
>
> So the C also requires you to make decisions about how in-depth a
> solution needs to be. If that information is available, then again you
> can choose a more efficient solution. Such as working only with 8-bit
> characters, or with 7-bit ASCII.
That's equally true of Python though. Python allows you to count bytes
as well if that's really what you want to do. C is not special in this
regard. The main difference is that Python offers a higher-level
interface to Unicode strings.
<snip>
>>> #include <stdio.h>
>>>
>>> int main(void) {
>>>
>>> char* msg = "Now is the time for all good men"
>>> " to come to the aid of their country";
>>> char* s;
>>> int counts[256]={0};
>>> int c;
>>>
>>> s=msg;
>>>
>>> while (c=*s++) ++counts[c];
>>>
>>> for (c=' '; c<256; ++c)
>>> if (counts[c]) printf("'%c': %d\n",c,counts[c]);
>>> }
>>
>> You allocate space for 256 byte counts but char might be signed. This
>> is another example of where script languages win over C -- usually fewer
>> bugs in corner cases.
>
> This is just the result of silly decision in C to make char signed.
Well, it's the result of the possibility that char might be signed but
I'm wary of trivialising it by saying "just".
> ... (But FWIW, I was testing with my own compiler where char is
> unsigned.)
>
> You would expect thorough testing however to pick up things like
> this.
Unless you test with compiler that uses unsigned char. If a program is
distributed as source you need to be sure it makes no unfounded
assumptions about other compilers.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-22 10:21 -0700 |
| Message-ID | <lnmv90aqgf.fsf@kst-u.example.com> |
| In reply to | #112830 |
bartc <bc@freeuk.com> writes:
[...]
> This is just the result of silly decision in C to make char signed.
>
> And all compilers I've just tested make it signed, with default options.
> (But FWIW, I was testing with my own compiler where char is unsigned.)
As you know, the signedness of plain char is implementation-defined.
The historical reasons for this have been discussed here before.
--
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]
| From | bartc <bc@freeuk.com> |
|---|---|
| Date | 2017-06-22 18:26 +0100 |
| Message-ID | <Y4T2B.31574$ZH4.15280@fx10.am4> |
| In reply to | #112840 |
On 22/06/2017 18:21, Keith Thompson wrote: > bartc <bc@freeuk.com> writes: > [...] >> This is just the result of [a] silly decision in C to make char signed. >> >> And all compilers I've just tested make it signed, with default options. >> (But FWIW, I was testing with my own compiler where char is unsigned.) > > As you know, the signedness of plain char is implementation-defined. But IME it tends to be signed. It shouldn't matter (when programs allow for it). Yet it seems it does otherwise you would expect more instances of unsigned char as the default char type.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-06-22 20:41 +0200 |
| Message-ID | <oih2qq$902$1@dont-email.me> |
| In reply to | #112841 |
On 22/06/17 19:26, bartc wrote: > On 22/06/2017 18:21, Keith Thompson wrote: >> bartc <bc@freeuk.com> writes: >> [...] >>> This is just the result of [a] silly decision in C to make char signed. >>> >>> And all compilers I've just tested make it signed, with default options. >>> (But FWIW, I was testing with my own compiler where char is unsigned.) >> >> As you know, the signedness of plain char is implementation-defined. > > But IME it tends to be signed. On x86 it is usually signed. On other targets, it can be different. > > It shouldn't matter (when programs allow for it). Yet it seems it does > otherwise you would expect more instances of unsigned char as the > default char type. > The signedness of char should not matter. If you need an unsigned char, use unsigned char (or uint8_t if that is more accurate). If you need a signed char, use signed char (or int8_t).
[toc] | [prev] | [next] | [standalone]
| From | Richard Heathfield <rjh@cpax.org.uk> |
|---|---|
| Date | 2017-06-22 19:59 +0100 |
| Message-ID | <oih3s0$cai$1@dont-email.me> |
| In reply to | #112845 |
On 22/06/17 19:41, David Brown wrote: > On 22/06/17 19:26, bartc wrote: >> On 22/06/2017 18:21, Keith Thompson wrote: <snip> >>> As you know, the signedness of plain char is implementation-defined. >> >> But IME it tends to be signed. > > On x86 it is usually signed. On other targets, it can be different. On IBM mainframe systems (eg MVS), it is often unsigned. (I /think/ it's always unsigned on systems that use EBCDIC, but I don't know for sure, so I'll stick to 'often' for now.) > The signedness of char should not matter. If you need an unsigned char, > use unsigned char (or uint8_t if that is more accurate). If you need a > signed char, use signed char (or int8_t). Agreed. -- Richard Heathfield Email: rjh at cpax dot org dot uk "Usenet is a strange place" - dmr 29 July 1999 Sig line 4 vacant - apply within
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-06-22 12:28 -0700 |
| Message-ID | <lnefubbz59.fsf@kst-u.example.com> |
| In reply to | #112846 |
Richard Heathfield <rjh@cpax.org.uk> writes:
> On 22/06/17 19:41, David Brown wrote:
>> On 22/06/17 19:26, bartc wrote:
>>> On 22/06/2017 18:21, Keith Thompson wrote:
>
> <snip>
>
>>>> As you know, the signedness of plain char is implementation-defined.
>>>
>>> But IME it tends to be signed.
>>
>> On x86 it is usually signed. On other targets, it can be different.
>
> On IBM mainframe systems (eg MVS), it is often unsigned. (I /think/ it's
> always unsigned on systems that use EBCDIC, but I don't know for sure,
> so I'll stick to 'often' for now.)
Assuming CHAR_BIT==8 (and I seriously doubt that an EBCDIC-based
implementation would have CHAR_BIT>8), plain char has to be unsigned
in an EBCDIC implementation.
6.2.5p3: "If a member of the basic execution character set is stored
in a char object, its value is guaranteed to be nonnegative."
Most members of the basic execution character set, including all
the letters and digits, have EBCDIC codes exceeding 127.
[...]
--
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]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2017-06-21 09:49 -0400 |
| Message-ID | <oidt9t$cga$1@jstuckle.eternal-september.org> |
| In reply to | #112752 |
On 6/20/2017 9:37 PM, DFS wrote:
> On 6/20/2017 9:05 PM, Ben Bacarisse wrote:
>> DFS <nospam@dfs.com> writes:
>> <snip>
>>> In python I would've said groups = sorted(set(data)) and been done
>>> with it!
>>
>> Yes. Why are you using C? It looks like this is the kind of program at
>> which a simple scripting language excels. (This is a genuine question.
>> I'm interested in why people use C and for what. Often it's just to try
>> it out, but maybe you have some other reason.)
>
> Mainly I love the blazing execution speed of C.
>
> I want to learn it well enough to understand or modify various open
> source code.
>
> I like that it's 'close to the metal'.
>
> Makes me a better programmer, too.
>
> Currently I do it only as a hobby, but it would be nice to put on a
> resume and be able to use C on the job if needed.
>
>
> Why do you use C?
>
>
>
>> By the way, C also has a sort function called qsort.
>
> I tried qsort at one point and didn't like it.
> I'd rather:
>
> char groups2[g];
> for (i = 0; i < g-1 ; i++)
> {
> for (j = i + 1; j < g; j++)
> {
> if (strcmp(groups[i], groups[j]) > 0)
> {
> strcpy(groups2, groups[i]);
> strcpy(groups[i], groups[j]);
> strcpy(groups[j], groups2);
> }
> }
> }
>
Bad code. What is 'g'? Is it the length of the longest element in the
array (groups[g]) - in which case your array counter will go out of
bounds. Or is it the number of elements in the groups array (j < g) -
in which case you can go beyond the end of the array with
strcpy(groups2, groups[i])?
Use qsort - it's already debugged - and much faster than your method.
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | DFS <nospam@dfs.com> |
|---|---|
| Date | 2017-06-21 10:36 -0400 |
| Message-ID | <oie01l$m9p$3@dont-email.me> |
| In reply to | #112776 |
On 6/21/2017 9:49 AM, Jerry Stuckle wrote:
> On 6/20/2017 9:37 PM, DFS wrote:
>> char groups2[g];
>> for (i = 0; i < g-1 ; i++)
>> {
>> for (j = i + 1; j < g; j++)
>> {
>> if (strcmp(groups[i], groups[j]) > 0)
>> {
>> strcpy(groups2, groups[i]);
>> strcpy(groups[i], groups[j]);
>> strcpy(groups[j], groups2);
>> }
>> }
>> }
>>
>
> Bad code.
Bad attitude.
> What is 'g'? Is it the length of the longest element in the
> array (groups[g]) - in which case your array counter will go out of
> bounds. Or is it the number of elements in the groups array (j < g) -
> in which case you can go beyond the end of the array with
> strcpy(groups2, groups[i])?
The latter + 1
> Use qsort - it's already debugged - and much faster than your method.
I'll take another look at it.
[toc] | [prev] | [next] | [standalone]
| From | Jerry Stuckle <jstucklex@attglobal.net> |
|---|---|
| Date | 2017-06-21 14:15 -0400 |
| Message-ID | <oiectj$5g2$1@jstuckle.eternal-september.org> |
| In reply to | #112781 |
On 6/21/2017 10:36 AM, DFS wrote:
> On 6/21/2017 9:49 AM, Jerry Stuckle wrote:
>> On 6/20/2017 9:37 PM, DFS wrote:
>
>
>>> char groups2[g];
>>> for (i = 0; i < g-1 ; i++)
>>> {
>>> for (j = i + 1; j < g; j++)
>>> {
>>> if (strcmp(groups[i], groups[j]) > 0)
>>> {
>>> strcpy(groups2, groups[i]);
>>> strcpy(groups[i], groups[j]);
>>> strcpy(groups[j], groups2);
>>> }
>>> }
>>> }
>>>
>>
>> Bad code.
>
> Bad attitude.
>
So calling attention to your bad code is "bad attitude"?
>
>> What is 'g'? Is it the length of the longest element in the
>> array (groups[g]) - in which case your array counter will go out of
>> bounds. Or is it the number of elements in the groups array (j < g) -
>> in which case you can go beyond the end of the array with
>> strcpy(groups2, groups[i])?
>
> The latter + 1
>
Which means your strcpy may overwrite memory.
Bad code.
>
>
>> Use qsort - it's already debugged - and much faster than your method.
>
> I'll take another look at it.
>
>
>
--
==================
Remove the "x" from my email address
Jerry Stuckle
jstucklex@attglobal.net
==================
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-06-21 15:10 +0100 |
| Message-ID | <87injpa0tj.fsf@bsb.me.uk> |
| In reply to | #112752 |
DFS <nospam@dfs.com> writes: <snip> > Why do you use C? I don't use it much anymore. When I last did, there was pretty much no choice. That's not to say I wouldn't have if there had been a choice because I was mainly doing Unix systems programming and it would have been the obvious language to use anyway. <snip> -- Ben.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c
csiph-web