digitalmars.D - How to use sprintf
- Justin Hanekom (14/14) Apr 24 2011 Hi all,
- dsimcha (6/20) Apr 24 2011 sprintf is a C function. The string you passed needs to be
- Steven Schveighoffer (11/39) Apr 25 2011 This is not true. sprintf does not care if the destination buffer is ze...
- Vladimir Panteleev (7/9) Apr 25 2011 Casting a string to char* is exactly the same as using the .ptr property...
- Robert Clipsham (7/13) Apr 25 2011 Not when a string is defined internally as struct { size_t length;
- Vladimir Panteleev (6/18) Apr 25 2011 Try it.
- Steven Schveighoffer (5/21) Apr 25 2011 I thought that "feature" was removed from D2? Just tested it, and it's ...
- Robert Clipsham (7/11) Apr 25 2011 Thanks for putting my mind at ease, I just spent ten minutes writing
- Daniel Gibson (11/38) Apr 25 2011 I don't think it's a good idea to remove it - that would probably
- bearophile (5/6) Apr 25 2011 It muds the semantic of the language, adding another special case. I thi...
- Daniel Gibson (13/19) Apr 25 2011 No. Casting other structs (*not* pointer to struct) is in fact illegal.
- Steven Schveighoffer (4/24) Apr 25 2011 simpler language spec/compiler :)
- bearophile (4/5) Apr 25 2011 Here there are several people that use D that find surprising things in ...
- bearophile (7/12) Apr 25 2011 It makes the language more ugly, more complex, and it will cause bugs an...
- Adam D. Ruppe (7/9) Apr 25 2011 It's probably meant to make interaction with C a little easier. In
- Steven Schveighoffer (7/41) Apr 25 2011 The address of the struct is &arr. There is no conflict here, and I
- Alexander (4/10) Apr 26 2011 How exactly this feature will be removed? Disallowing opCast() which d...
- Steven Schveighoffer (6/18) Apr 26 2011 Currently, casting an array to a pointer is a special case of casting in...
- Alexander (4/5) Apr 26 2011 To me (coming from C/C++) it looks more natural to cast instead if usi...
- Daniel Gibson (6/8) Apr 26 2011 No, in D arrays are not just pointers. It's indeed a struct that
- Alexander (6/9) Apr 26 2011 If this is a struct, then there is no "special compiler handling" need...
- Steven Schveighoffer (36/47) Apr 26 2011 A "struct" is simply a group of members used as data, and a group of
- Alexander (4/5) Apr 26 2011 Indeed, your arguments are very convincing - being a person like "I kn...
- Steven Schveighoffer (4/5) Apr 26 2011 The compiler should tell you all the places where you have to fix the ol...
- Peter Alexander (9/14) Apr 26 2011 This is wrong on two levels:
- Robert Clipsham (6/22) Apr 25 2011 That's weird, I really didn't expect that :< Don't suppose you could
- Steven Schveighoffer (6/22) Apr 25 2011 BTW, that got me curious what the real failure of the original code was,...
- Steven Schveighoffer (6/30) Apr 25 2011 Regardless of all this, cast(char *)buffer is *not* recommended D code, ...
- Vladimir Panteleev (8/10) Apr 25 2011 I'm pretty sure I learned of this trick from reading some Phobos code.
- Andrej Mitrovic (2/2) Apr 25 2011 Isn't it dangerous to pass a D string and let the C code overwrite the
- Steven Schveighoffer (5/7) Apr 25 2011 Yes. Using sprintf is dangerous regardless of what language you are
- Timon Gehr (1/3) Apr 26 2011 There is a possibility for buffer overflow.
- Andrej Mitrovic (2/5) Apr 26 2011 No, I mean the C function will overwrite an immutable string.
- Steven Schveighoffer (14/21) Apr 26 2011 D would not allow you to pass a .ptr field of an immutable string, becau...
- Andrej Mitrovic (11/33) Apr 26 2011 Yes I was refering to casting. It would segfault on Linux but probably
- bearophile (4/9) Apr 26 2011 Casting is dangerous in general, but it becomes less dangerous when you ...
- Adam D. Ruppe (8/8) Apr 24 2011 You might try the format() function instead:
- Justin Hanekom (9/9) Apr 24 2011 Thanks Adam,
- Benjamin Thaut (11/11) Apr 24 2011 If you just want to format a string use std.string.format.
- %Justin Hanekom (2/2) Apr 24 2011 Thanks dsimcha, Ben, and Adam,
Hi all, I have what should be an *extremely* simple question that Im banging my head against: how to use sprintf to format something to a string. I have tried: import std.stdio; ... auto buffer = new char[12]; auto chars_written = sprintf(cast(char *) buffer, "%d", 12345); writeln(chars_written); and various other ways of getting the buffer into sprintf, but no matter what I do the program seems to die when sprintf is called. What I'm ultimately trying to do here is format a number with thousands separated by commas. Any idea? Thanks, Justin
Apr 24 2011
On 4/24/2011 5:22 PM, Justin Hanekom wrote:Hi all, I have what should be an *extremely* simple question that Im banging my head against: how to use sprintf to format something to a string. I have tried: import std.stdio; ... auto buffer = new char[12]; auto chars_written = sprintf(cast(char *) buffer, "%d", 12345); writeln(chars_written); and various other ways of getting the buffer into sprintf, but no matter what I do the program seems to die when sprintf is called. What I'm ultimately trying to do here is format a number with thousands separated by commas. Any idea? Thanks, Justinsprintf is a C function. The string you passed needs to be zero-terminated. Since it's not, sprintf probably keeps trying to write more stuff until it segfaults, because it never finds the zero terminator. See std.string.toStringz (http://www.digitalmars.com/d/2.0/phobos/std_string.html#toStringz).
Apr 24 2011
On Sun, 24 Apr 2011 17:22:39 -0400, dsimcha <dsimcha yahoo.com> wrote:On 4/24/2011 5:22 PM, Justin Hanekom wrote:This is not true. sprintf does not care if the destination buffer is zero terminated, because it actually writes the zero. The requirement is simply that the buffer be large enough to handle the data. Even the safer version of sprintf (snprintf) does not require the buffer to be zero-terminated before calling the function. The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr. This should work: auto chars_written = sprintf(buffer.ptr, "%d", 12345); -SteveHi all, I have what should be an *extremely* simple question that Im banging my head against: how to use sprintf to format something to a string. I have tried: import std.stdio; ... auto buffer = new char[12]; auto chars_written = sprintf(cast(char *) buffer, "%d", 12345); writeln(chars_written); and various other ways of getting the buffer into sprintf, but no matter what I do the program seems to die when sprintf is called. What I'm ultimately trying to do here is format a number with thousands separated by commas. Any idea? Thanks, Justinsprintf is a C function. The string you passed needs to be zero-terminated. Since it's not, sprintf probably keeps trying to write more stuff until it segfaults, because it never finds the zero terminator. See std.string.toStringz (http://www.digitalmars.com/d/2.0/phobos/std_string.html#toStringz).
Apr 25 2011
On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned. -- Best regards, Vladimir mailto:vladimir thecybershadow.net
Apr 25 2011
On 25/04/2011 15:56, Vladimir Panteleev wrote:On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer. -- Robert http://octarineparrot.com/The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:On 25/04/2011 15:56, Vladimir Panteleev wrote:Try it. -- Best regards, Vladimir mailto:vladimir thecybershadow.netOn Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On Mon, 25 Apr 2011 11:26:57 -0400, Vladimir Panteleev <vladimir thecybershadow.net> wrote:On Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:I thought that "feature" was removed from D2? Just tested it, and it's definitely not removed yet. But it will be :) -SteveOn 25/04/2011 15:56, Vladimir Panteleev wrote:Try it.On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On 25/04/2011 16:36, Steven Schveighoffer wrote:Thanks for putting my mind at ease, I just spent ten minutes writing various variations and disassembling them trying to figure out what was going on! -- Robert http://octarineparrot.com/Try it.I thought that "feature" was removed from D2? Just tested it, and it's definitely not removed yet. But it will be :) -Steve
Apr 25 2011
Am 25.04.2011 17:36, schrieb Steven Schveighoffer:On Mon, 25 Apr 2011 11:26:57 -0400, Vladimir Panteleev <vladimir thecybershadow.net> wrote:I don't think it's a good idea to remove it - that would probably (silently) break a lot of code. As I see it there are two possibilities to remove it: 1. completely forbid casting an array to a pointer (even to get the address of the struct) - I don't think this is desirable? 2. silently change the behaviour to return the address of the struct instead of .ptr - silently breaks code, even worse. So why not just leave it the way it is? Cheers, - DanielOn Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:I thought that "feature" was removed from D2? Just tested it, and it's definitely not removed yet. But it will be :) -SteveOn 25/04/2011 15:56, Vladimir Panteleev wrote:Try it.On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
Daniel Gibson:So why not just leave it the way it is?It muds the semantic of the language, adding another special case. I think the right (right = shared with other structs) semantics here is to return the address of the length field. My experience based seeing it happen again and again tells me that every time you leave some muddy semantics in a language, sooner or later that comes back to bite your bum. Another example is the property semantics, some people don't want to fix the current wrong behaviour. Bye, bearophile
Apr 25 2011
Am 25.04.2011 19:30, schrieb bearophile:Daniel Gibson:No. Casting other structs (*not* pointer to struct) is in fact illegal. (This just occured to me, I didn't think of this when writing the other post) If you want the address of the struct you write void *foo = cast(void*)&s; So the only sane thing to do is either to forbid casting an array to a pointer or to return .ptr like it's done now. I don't see the harm in the latter, but then again arr.ptr is shorter and more readable. So my only remaining objection is: Allowing it doesn't hurt (IMHO) and disallowing may break existing code, so why bother ;) Cheers, - DanielSo why not just leave it the way it is?It muds the semantic of the language, adding another special case. I think the right (right = shared with other structs) semantics here is to return the address of the length field.
Apr 25 2011
On Mon, 25 Apr 2011 13:40:30 -0400, Daniel Gibson <metalcaedes gmail.com> wrote:Am 25.04.2011 19:30, schrieb bearophile:simpler language spec/compiler :) -SteveDaniel Gibson:No. Casting other structs (*not* pointer to struct) is in fact illegal. (This just occured to me, I didn't think of this when writing the other post) If you want the address of the struct you write void *foo = cast(void*)&s; So the only sane thing to do is either to forbid casting an array to a pointer or to return .ptr like it's done now. I don't see the harm in the latter, but then again arr.ptr is shorter and more readable. So my only remaining objection is: Allowing it doesn't hurt (IMHO) and disallowing may break existing code, so why bother ;)So why not just leave it the way it is?It muds the semantic of the language, adding another special case. I think the right (right = shared with other structs) semantics here is to return the address of the length field.
Apr 25 2011
Steven Schveighoffer:simpler language spec/compiler :)Here there are several people that use D that find surprising things in a tiny piece of code, and discuss about it with many posts. This is the best demonstration that this is a special case that adds complexity to the language, that needs to be removed. A special case is worth keeping only in special situations, only when it gives a significant advantage. This is not the case. Bye, bearophile
Apr 25 2011
Daniel Gibson:No. Casting other structs (*not* pointer to struct) is in fact illegal. (This just occured to me, I didn't think of this when writing the other post)Right, sorry.So my only remaining objection is: Allowing it doesn't hurt (IMHO) and disallowing may break existing code, so why bother ;)It makes the language more ugly, more complex, and it will cause bugs and problems, as all other similar muddy shortcuts. I have a bug report about this that is sleeping there since 2010-03-20, among several other reports of similar anti-features: http://d.puremagic.com/issues/show_bug.cgi?id=3990 I don't need a perfect language, but I fail to understand why similar little pieces of trash are wanted in any language. bearophile
Apr 25 2011
bearophile:I don't need a perfect language, but I fail to understand why similar little pieces of trash are wanted in any language.It's probably meant to make interaction with C a little easier. In C, arrays and pointers are interchangeable in a lot of places. It'd make D code look more like the C code it is interacting with. I don't think we need it, since the .ptr property does the job, but the reasoning probably made a lot of sense at the time it was brought in.
Apr 25 2011
On Mon, 25 Apr 2011 12:47:20 -0400, Daniel Gibson <metalcaedes gmail.com> wrote:Am 25.04.2011 17:36, schrieb Steven Schveighoffer:The address of the struct is &arr. There is no conflict here, and I believe this is the solution that will be implemented. I thought the compiler disabled this "feature" a while ago, I know that Don went through and removed all the casts that were in the runtime. -SteveOn Mon, 25 Apr 2011 11:26:57 -0400, Vladimir Panteleev <vladimir thecybershadow.net> wrote:I don't think it's a good idea to remove it - that would probably (silently) break a lot of code. As I see it there are two possibilities to remove it: 1. completely forbid casting an array to a pointer (even to get the address of the struct) - I don't think this is desirable?On Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:I thought that "feature" was removed from D2? Just tested it, and it's definitely not removed yet. But it will be :) -SteveOn 25/04/2011 15:56, Vladimir Panteleev wrote:Try it.On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On 25.04.2011 17:36, Steven Schveighoffer wrote:How exactly this feature will be removed? Disallowing opCast() which does this explicitly? ;) Regards, /AlexanderI thought that "feature" was removed from D2? Just tested it, and it's definitely not removed yet. But it will be :)Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.Try it.
Apr 26 2011
On Tue, 26 Apr 2011 06:31:39 -0400, Alexander <aldem+dmars nk7.net> wrote:On 25.04.2011 17:36, Steven Schveighoffer wrote:Currently, casting an array to a pointer is a special case of casting in the compiler, which basically returns arr.ptr. However, that functionality is already available via arr.ptr. I think the special case can be disallowed. opCast will remain as-is. -SteveHow exactly this feature will be removed? Disallowing opCast() which does this explicitly? ;)I thought that "feature" was removed from D2? Just tested it, and it's definitely not removed yet. But it will be :)Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.Try it.
Apr 26 2011
On 26.04.2011 13:59, Steven Schveighoffer wrote:Currently, casting an array to a pointer is a special case of casting in the compiler, which basically returns arr.ptr. However, that functionality is already available via arr.ptr.To me (coming from C/C++) it looks more natural to cast instead if using arr.ptr. After all, array is a pointer (=reference), and arrays are not structs (=values), so I see no reason to disallow this, to be honest. And, indeed, once disallowed, it will break a lot of existing code... /Alexander
Apr 26 2011
Am 26.04.2011 15:11, schrieb Alexander:After all, array is a pointer (=reference), and arrays are not structs (=values), so I see no reason to disallow this, to be honest.No, in D arrays are not just pointers. It's indeed a struct that contains the length (arr.length) and the pointer (arr.ptr). This makes arrays in D a lot safer and also easier to use than in C. Cheers, - Daniel
Apr 26 2011
On 26.04.2011 15:21, Daniel Gibson wrote:No, in D arrays are not just pointers. It's indeed a struct that contains the length (arr.length) and the pointer (arr.ptr).If this is a struct, then there is no "special compiler handling" needed to cast a struct to a pointer using opCast() (except for static arrays). But, from programmer point of view, array is not a struct, just a type with some properties, "struct" is hidden somewhere internally.This makes arrays in D a lot safer and also easier to use than in C.I see no danger in using cast(void *)Array instead of Array.ptr, if semantic is known in advance (and it is). IMHO, it would be not so good if this handling will be disallowed at some point. /Alexander
Apr 26 2011
On Tue, 26 Apr 2011 10:08:21 -0400, Alexander <aldem+dmars nk7.net> wrote:On 26.04.2011 15:21, Daniel Gibson wrote:A "struct" is simply a group of members used as data, and a group of functions that accept that member as the first parameter. The same is true for arrays, although it's not defined anywhere as a "struct." Arrays are special types to the compiler, they are not ordinary structures. However, more and more they are being extended in the library. In reality, they could just be treated as normal types with the library defining the properties, thanks to the ability to add array properties. Already associative arrays are done that way. The way it is implemented is a mix between newer style functions defined in the library and original functions that were done way back when D did not have the ability to add array properties.No, in D arrays are not just pointers. It's indeed a struct that contains the length (arr.length) and the pointer (arr.ptr).If this is a struct, then there is no "special compiler handling" needed to cast a struct to a pointer using opCast() (except for static arrays). But, from programmer point of view, array is not a struct, just a type with some properties, "struct" is hidden somewhere internally.Casting overrides the type system. It's always a red flag. Example: void foo() { char[] buffer = new char[12]; ... auto charptr = cast(char *)buffer; sometime down the road, you decide buffer should be a const input parameter: void foo(const(char)[] buffer) { ... auto charptr = cast(char *)buffer; // oops! there goes const! or if you decide later to use wchar[], or whatever. casting says "I know what I'm doing" and should be only used very sparingly. It should not be a tool of first resort. compare that to: char *charptr = buffer.ptr; // throws an error if buffer is not a char[] or even more robust: auto charptr = buffer.ptr; // now all your code is upgraded to use the newest type you decide on. In other words, casting an array to a pointer is first of all a hack, and second of all 100% unnecessary. It's just wasting compiler code space. -SteveThis makes arrays in D a lot safer and also easier to use than in C.I see no danger in using cast(void *)Array instead of Array.ptr, if semantic is known in advance (and it is).
Apr 26 2011
On 26.04.2011 19:15, Steven Schveighoffer wrote:In other words, casting an array to a pointer is first of all a hack, and second of all 100% unnecessary. It's just wasting compiler code space.Indeed, your arguments are very convincing - being a person like "I know what I'm doing" I typically forget about those things... Then, there is one issue left - old code... :) /Alexander
Apr 26 2011
On Tue, 26 Apr 2011 16:27:00 -0400, Alexander <aldem+dmars nk7.net> wrote:Then, there is one issue left - old code... :)The compiler should tell you all the places where you have to fix the old code ;) -Steve
Apr 26 2011
On 26/04/11 2:11 PM, Alexander wrote:On 26.04.2011 13:59, Steven Schveighoffer wrote:This is wrong on two levels: 1. In D, an array is not a pointer. It is a struct with two members: a length and a pointer. It is not the same as C or C++ array. 2. Even in C++, an array is not a pointer. The type of an array in C++ is T[N] whereas a pointer is T*. The only reasons you can pass an array into a function that accepts a pointer is because of an implicit conversion. Arrays are implemented as pointers, but they are not the same type.Currently, casting an array to a pointer is a special case of casting in the compiler, which basically returns arr.ptr. However, that functionality is already available via arr.ptr.To me (coming from C/C++) it looks more natural to cast instead if using arr.ptr. After all, array is a pointer (=reference), and arrays are not structs (=values), so I see no reason to disallow this, to be honest. And, indeed, once disallowed, it will break a lot of existing code... /Alexander
Apr 26 2011
On 25/04/2011 16:26, Vladimir Panteleev wrote:On Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:That's weird, I really didn't expect that :< Don't suppose you could explain why this behavior occurs? -- Robert http://octarineparrot.com/On 25/04/2011 15:56, Vladimir Panteleev wrote:Try it.On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On Mon, 25 Apr 2011 11:26:57 -0400, Vladimir Panteleev <vladimir thecybershadow.net> wrote:On Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:BTW, that got me curious what the real failure of the original code was, and I tried it. Turns out, it actually runs successfully! So I can only guess that the OP didn't post his actually failing code. -SteveOn 25/04/2011 15:56, Vladimir Panteleev wrote:Try it.On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On Mon, 25 Apr 2011 11:39:28 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Mon, 25 Apr 2011 11:26:57 -0400, Vladimir Panteleev <vladimir thecybershadow.net> wrote:Regardless of all this, cast(char *)buffer is *not* recommended D code, and will likely fail in some future 2.x version of the compiler. Man, I should learn to collect all my thoughts before posting :) -SteveOn Mon, 25 Apr 2011 18:21:16 +0300, Robert Clipsham <robert octarineparrot.com> wrote:BTW, that got me curious what the real failure of the original code was, and I tried it. Turns out, it actually runs successfully! So I can only guess that the OP didn't post his actually failing code.On 25/04/2011 15:56, Vladimir Panteleev wrote:Try it.On Mon, 25 Apr 2011 17:19:12 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Not when a string is defined internally as struct { size_t length; immutable(char)* ptr; }. Casting to char* is a pointer to the start of the length, not the pointer.The problem the OP has is he is casting buffer to a char *. He should just use buffer.ptr.Casting a string to char* is exactly the same as using the .ptr property, as far as generated code is concerned.
Apr 25 2011
On Mon, 25 Apr 2011 18:42:32 +0300, Steven Schveighoffer <schveiguy yahoo.com> wrote:Regardless of all this, cast(char *)buffer is *not* recommended D code, and will likely fail in some future 2.x version of the compiler.I'm pretty sure I learned of this trick from reading some Phobos code. Perhaps this behavior was implemented before the .ptr property for dynamic arrays? -- Best regards, Vladimir mailto:vladimir thecybershadow.net
Apr 25 2011
Isn't it dangerous to pass a D string and let the C code overwrite the string, regardless of char* vs .ptr field?
Apr 25 2011
On Mon, 25 Apr 2011 12:55:38 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Isn't it dangerous to pass a D string and let the C code overwrite the string, regardless of char* vs .ptr field?Yes. Using sprintf is dangerous regardless of what language you are using. It is advised to use D equivalents. -Steve
Apr 25 2011
Isn't it dangerous to pass a D string and let the C code overwrite the string, regardless of char* vs .ptr field?There is a possibility for buffer overflow.
Apr 26 2011
On 4/26/11, Timon Gehr <timon.gehr gmx.ch> wrote:No, I mean the C function will overwrite an immutable string.Isn't it dangerous to pass a D string and let the C code overwrite the string, regardless of char* vs .ptr field?There is a possibility for buffer overflow.
Apr 26 2011
On Tue, 26 Apr 2011 13:11:20 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 4/26/11, Timon Gehr <timon.gehr gmx.ch> wrote:D would not allow you to pass a .ptr field of an immutable string, because the type would be immutable(char)* and wouldn't implicitly cast to the required char* argument. Casting, however, would mask that problem and probably overwrite immutable data (and probably segfault on Linux). Another example of why casting is bad. for example, this should throw an error: import std.stdio; void main() { sprintf("buf".ptr, "%d", 12345); } -SteveNo, I mean the C function will overwrite an immutable string.Isn't it dangerous to pass a D string and let the C code overwrite the string, regardless of char* vs .ptr field?There is a possibility for buffer overflow.
Apr 26 2011
On 4/26/11, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Tue, 26 Apr 2011 13:11:20 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Yes I was refering to casting. It would segfault on Linux but probably not on Windows, which brings us to the infamous string literal assignment bug: void main() { "hello" = "red"; string x = "hello"; assert(x == "red"); } http://d.puremagic.com/issues/show_bug.cgi?id=4539On 4/26/11, Timon Gehr <timon.gehr gmx.ch> wrote:D would not allow you to pass a .ptr field of an immutable string, because the type would be immutable(char)* and wouldn't implicitly cast to the required char* argument. Casting, however, would mask that problem and probably overwrite immutable data (and probably segfault on Linux). Another example of why casting is bad. for example, this should throw an error: import std.stdio; void main() { sprintf("buf".ptr, "%d", 12345); } -SteveNo, I mean the C function will overwrite an immutable string.Isn't it dangerous to pass a D string and let the C code overwrite the string, regardless of char* vs .ptr field?There is a possibility for buffer overflow.
Apr 26 2011
Steven Schveighoffer:D would not allow you to pass a .ptr field of an immutable string, because the type would be immutable(char)* and wouldn't implicitly cast to the required char* argument. Casting, however, would mask that problem and probably overwrite immutable data (and probably segfault on Linux). Another example of why casting is bad.Casting is dangerous in general, but it becomes less dangerous when you have some different specialized casts: if you have a cast syntax that only change the const-ness of something (mutable <-> const <-> immutable), and a different syntax (syntax = "any way to express a semantics") to change other aspects of the type, it becomes less easy to cast const-ness away by mistake. Bye, bearophile
Apr 26 2011
You might try the format() function instead: http://dpldocs.info/std.string.format Though, I don't think it does thousands grouping, so it might not work for you. If you need C's sprintf, make sure the strings are zero terminated and that you're passing pointers to them: char[10] buffer; sprintf(buffer.ptr, toStringz(formatString), args...);
Apr 24 2011
Thanks Adam, My main problem, I guess, is that I can't seem to find the documentation for these functions in D. I'll be checking out the link you sent for the format function shortly. I don't expect the function to be able to do the thousands formatting for me (C's version works if you use "%'d" [notice the '] and have LC_LOCALE set) but just want to get a string that I can then format. Thanks for your speedy, detailed, and very informative reply! Justin
Apr 24 2011
If you just want to format a string use std.string.format. import std.string; int i=1; float f=2.5f; string s = "test"; string output = format("%s %s %s",i,f,s); If you use the %s placeholder the type will automatically be determined and printed out correctly. -- Kind Regards Benjamin Thaut
Apr 24 2011
Thanks dsimcha, Ben, and Adam, You guys are great!
Apr 24 2011