Jump to page: 1 2 3
Thread overview
July 13
The idea is printf is already largely safe:

```
printf("number = %d\n", 3);
```
is perfectly safe.

Unsafe problems:

1. if the arguments and their types do not match the format string. D already checks for that, so we're good there.

2. if a pointer is passed to %s:

```
char* name;
printf("name = %s\n", name);
```
That's unsafe. We normally fix this with:

```
char[] name;
printf("name = %.*s\n", cast(int)name.length, name.ptr);
```
Which is safe, because we know how printf() works. I propose that the compiler rewrite:

```
char[] name;
printf("name = %s\n", name);
```
into:
```
printf("name = %.*s\n", cast(int)name.length, name.ptr);
```
(and mark any other use of %.*s as unsafe)

We can go further, and realize that since we already check the format string against the arguments, we can rewrite the format string to match the arguments:

```
printf("number = %s\n", 3);
```
becomes:
```
printf("number = %d\n", 3);
```
which makes it much simpler to use printf. I can never remember which format is for size_t, for example.

The one format specification (I forgot which one) which assigns a int value through a pointer, can simply be marked as unsafe.

Of course, this only applies if the format string is a literal, not a variable.

Since dmd already scans and checks the format string against the argument list, most of the work for this proposal is already done.
July 13
On Saturday, 13 July 2024 at 20:39:32 UTC, Walter Bright wrote:
> printf

I basically never use the old c printf syntax and Im pretty sure thats true of 95% of people here, as far as I know theres one usecase for printf and thats picking float significant digits.

Printing in a template lang with a pretty solid print api norm(as far as I know everyone on board with toString) have far better methods then the c norms. Templates and a lib level decisions should be the way forward; now if you want to make those better(such as handling the float digit overloads) this would be a point of interest for me

Off the top of my head, you should*nt* verify c formated strings at all, those cryptic letters are form a very long dead era; if your changing the api but want to make it follow to old way, drop everything but '%' scanning i.e. `printf("hello %, today is %.\n","bob",days.monday);`

July 14
On Saturday, 13 July 2024 at 20:39:32 UTC, Walter Bright wrote:
> The idea is printf is already largely safe:

This is trivially achievable with IES. Do not waste time on making the compiler have some special case here.

-Steve
July 13
I understand the desire to use modern write().

But there is a place for a lightweight way to do formatted writing.

1. If you're just linking with the stdc library, there is no write().

2. printf is probably the most debugged and optimized piece of code that has ever existed. Borland C recoded it in hand-optimized assembler, which was a brilliant move as its fast printf covered for a lot of weakness in its poor code generator

3. write() won't work until pretty much everything in the compiler works. With printf, I can get hello world to work needing only a minimally functional compiler

4. can't use Phobos in dmd's source code, because if a working Phobos was required, it becomes much much harder to bootstrap it

5. most any use of write() causes a rather large pile of template bloat to be inserted into the object file. This makes life difficult when trying to isolate a bug.

Currently, dmd's checking of the arguments against the format string has already eliminated a large chunk of the problems with printf. It enabled the removal of dozens of bugs in the dmd code base. A big win!

My proposal is pretty lightweight, the heavy lifting was already done with the argument checking. It enables @safe use of printf, and removes the temptation to rely on char* strings instead of char[] strings.
July 14
While this does seem to be useful, there is an issue for adoption with dmd.

It'll fool you into thinking it works with the latest compiler when bootstrapping, and silently cause broken programs in older ones.

Steven is right, interpolated string wrapper around printf would be a better option.

July 14
On 7/13/24 22:39, Walter Bright wrote:
> I propose that the compiler rewrite:
> 
> ```
> char[] name;
> printf("name = %s\n", name);
> ```
> into:
> ```
> printf("name = %.*s\n", cast(int)name.length, name.ptr);
> ```
> (and mark any other use of %.*s as unsafe)

This part is actually not memory safe.


In general, I guess provided we can get it right, extending the `pragma(printf)` checks in `@safe` code is indeed an improvement to the language, though I think not a lot of people need this.

You should probably have to mark the `printf` prototype as `@trusted` for this to work though. (There are `pragma(printf)` functions that still have a `@system` interface even when there is nothing wrong with the format string and arguments, e.g. `sprintf`.)

For everyone who is not aware, here's D's existing `printf` support:
https://dlang.org/spec/pragma.html#printf

Probably `pragma(scanf)` would need to get similar treatment.

July 15
On 7/13/2024 6:10 PM, Steven Schveighoffer wrote:
> This is trivially achievable with IES.

What is IES?
July 16
On 16/07/2024 6:25 AM, Walter Bright wrote:
> On 7/13/2024 6:10 PM, Steven Schveighoffer wrote:
>> This is trivially achievable with IES.
> 
> What is IES?

https://dlang.org/spec/istring.html
July 15
On 7/13/2024 11:39 PM, Richard (Rikki) Andrew Cattermole wrote:
> It'll fool you into thinking it works with the latest compiler when bootstrapping, and silently cause broken programs in older ones.

It won't be silent, as printf argument checking has been around for many years in dmd.


> Steven is right, interpolated string wrapper around printf would be a better option.

That's more work.

July 15
On 7/14/2024 7:06 AM, Timon Gehr wrote:
> On 7/13/24 22:39, Walter Bright wrote:
>> I propose that the compiler rewrite:
>>
>> ```
>> char[] name;
>> printf("name = %s\n", name);
>> ```
>> into:
>> ```
>> printf("name = %.*s\n", cast(int)name.length, name.ptr);
>> ```
>> (and mark any other use of %.*s as unsafe)
> 
> This part is actually not memory safe.

How is it not safe?


> In general, I guess provided we can get it right, extending the `pragma(printf)` checks in `@safe` code is indeed an improvement to the language, though I think not a lot of people need this.

*I* need it :-) It's an enabling feature, in that it enables me to much more fully transition dmd away from using 0 terminated strings.


> You should probably have to mark the `printf` prototype as `@trusted` for this to work though. (There are `pragma(printf)` functions that still have a `@system` interface even when there is nothing wrong with the format string and arguments, e.g. `sprintf`.)

It would apply to snprintf, but not sprintf which is not fixable.


> For everyone who is not aware, here's D's existing `printf` support:
> https://dlang.org/spec/pragma.html#printf
> 
> Probably `pragma(scanf)` would need to get similar treatment.

Possibly, but scanf is almost never used :-/

« First   ‹ Prev
1 2 3