Found by Dennis Ritchie, and reduced by Ivan Kazmenko, in d.learn: http://forum.dlang.org/thread/[email protected]
Tested through wine with DMD32 D Compiler v2.066.1.
No problem on linux. Couldn't test -m64 with wine.
Works fine with lengths up to 32767.
a.d (generates a long line):
----
import std.range, std.stdio;
void main () {'a'.repeat (100_000).writeln;}
----
b.d (tries to read it):
----
import core.stdc.stdio: printf, scanf;
import core.stdc.string: strlen;
void main () {
char [100_000 + 1] a;
scanf ("%s", a.ptr);
printf("%d\n", a.ptr.strlen); /* prints "32767", should print "100000" */
}
----
Compile and run:
----
dmd a.d && dmd b.d && (./a | ./b)
----
Comment #1 by gassa — 2015-03-21T20:27:31Z
Thank you for reporting it - and fixing the array size.
My system where it is reproducible is 64-bit Windows.
For me, "dmd -m32" gives the error, "dmd -m64" does not. So I changed the "hardware" selector from x86_64 to x86.
Comment #2 by home — 2015-03-21T21:51:58Z
I can confirm the problem. Interestingly, it occurs when trying to scanf a long string without whitespace immediately followed by \r\n. There was no problem when the line ended with just a \n, didn't end at all, or when the string was followed by whitespace and some other chars.
Comment #3 by gassa — 2015-03-21T22:12:32Z
(In reply to FG from comment #2)
> I can confirm the problem. Interestingly, it occurs when trying to scanf a
> long string without whitespace immediately followed by \r\n. There was no
> problem when the line ended with just a \n, didn't end at all, or when the
> string was followed by whitespace and some other chars.
Hmm, this is not the case here. What system do you use for testing?
Either converting line endings dos2unix, removing end-of-line sequence completely, or using any of the two following generators, I still get 32767:
gen2.d (generate two long words on a line)
-----
import std.range, std.stdio;
void main () {'a'.repeat (50000).repeat (2).join (' ').writeln;}
-----
gen3.d (generate one long and one short word on a line)
-----
import std.range, std.stdio;
void main () {['a'.repeat (100000).array, "b"].join (' ').writeln;}
-----
Comment #4 by home — 2015-03-21T22:29:31Z
Sorry, forget my comment. I was testing on the wrong files. Now that I corrected them I see that it always prints 32767, regardless of the situation I previously described.
Comment #5 by robert.schadek — 2024-12-07T13:35:02Z