Thread overview
Obtaining an address given a (run time) variable name
1 day ago
DLearner
1 day ago
DLearner
1 day ago
evilrat
1 day ago
DLearner
1 day ago
evilrat
19 hours ago
Paul Backus
19 hours ago
matheus
1 day ago

// In the code below, what fn needs to go in the commented-out line,
// to make the program print 7, 11 rather than 7, 7?

void main() {

   import std.stdio;

   int IntVar1 = 5;
   int IntVar2 = 7;
   int IntVar3 = 11;

   int*   wkVarAddr;
   char[] wkVarName;


   wkVarAddr = &IntVar2;
   writeln("*wkVarAddr = ", *wkVarAddr);

   wkVarName = cast(char[])("IntVar3");
//   wkVarAddr = fn (wkVarName);
   writeln("*wkVarAddr = ", *wkVarAddr);
}
1 day ago
On Monday, January 20, 2025 12:03:09 PM MST DLearner via Digitalmars-d-learn wrote:
> // In the code below, what fn needs to go in the commented-out
> line,
> // to make the program print 7, 11 rather than 7, 7?
>
> ```
> void main() {
>
>     import std.stdio;
>
>     int IntVar1 = 5;
>     int IntVar2 = 7;
>     int IntVar3 = 11;
>
>     int*   wkVarAddr;
>     char[] wkVarName;
>
>
>     wkVarAddr = &IntVar2;
>     writeln("*wkVarAddr = ", *wkVarAddr);
>
>     wkVarName = cast(char[])("IntVar3");
> //   wkVarAddr = fn (wkVarName);
>     writeln("*wkVarAddr = ", *wkVarAddr);
> }
> ```
>

Variable names are not a thing at runtime. They're entirely a compile time thing, and the generated code does not know or care that there even were names for variables in the source code. The compiled code is dealing with registers, not actual variables with names. Debug information will have some of that so that you can step through the source code in a debugger, but the generated code itself doesn't do anything with variable names or provide any way to access that information in your code. So, there's nowhere to look up the value of a variable by name at runtime. If you want that, you're going to have to store that information yourself somehow.

For instance, you could do something like a create an associative array with the variable name as the key and the address as the value.

    int*[string] addrs;
    addrs["IntVar1"] = &IntVar1;
    addrs["IntVar2"] = &IntVar2;
    addrs["IntVar3"] = &IntVar3;

    wkVarAddr = vars[wkVarName];

But the language isn't going to do anything like that for you automatically.

Also, there's really no reason to be doing anything with char[] instead of string unless you're specifically planning on mutating the elements in your string, and casting from a string literal to a char[] is almost never a good idea, because it means that you could end up mutating the elements, which would violate the type system guarantees - since immutable values are never supposed to be mutated, and the compiler will potentially make the assumption that an immutable value was not mutated (string is an alias for immutable(char)[], and string literals are strings). If you _do_ need to mutate the string for some reason, then use dup to get a mutable copy rather than casting the literal, e.g.

    char[] wkVarName = "IntVar3".dup;

- Jonathan M Davis



1 day ago
On Monday, 20 January 2025 at 19:54:19 UTC, Jonathan M Davis wrote:
> On Monday, January 20, 2025 12:03:09 PM MST DLearner via Digitalmars-d-learn wrote:
>> // In the code below, what fn needs to go in the commented-out
>> line,
>> // to make the program print 7, 11 rather than 7, 7?
>>
>> ```
>> void main() {
>>
>>     import std.stdio;
>>
>>     int IntVar1 = 5;
>>     int IntVar2 = 7;
>>     int IntVar3 = 11;
>>
>>     int*   wkVarAddr;
>>     char[] wkVarName;
>>
>>
>>     wkVarAddr = &IntVar2;
>>     writeln("*wkVarAddr = ", *wkVarAddr);
>>
>>     wkVarName = cast(char[])("IntVar3");
>> //   wkVarAddr = fn (wkVarName);
>>     writeln("*wkVarAddr = ", *wkVarAddr);
>> }
>> ```
>>
>
> Variable names are not a thing at runtime.
[...]
> But the language isn't going to do anything like that for you automatically.

Agreed, I need to think about this further.

>
> Also, there's really no reason to be doing anything with char[] instead of string
[...]
If you _do_ need to mutate the string for some
> reason, then use dup to get a mutable copy rather than casting the literal, e.g.
>
>     char[] wkVarName = "IntVar3".dup;

The reason for using char[] wasn't because there was a need to mutate the elements.
It was because my understanding was that in certain situations the string construct did not just produce a character array - it also produced the (to me horrible) concept of adding a x'00' immediately after the last character of the array.
Which could produce problems on concatenation, and doubt about the length of the string.
char[] just worked properly.




>
> - Jonathan M Davis


1 day ago
On Monday, 20 January 2025 at 22:32:02 UTC, DLearner wrote:
> It was because my understanding was that in certain situations the string construct did not just produce a character array - it also produced the (to me horrible) concept of adding a x'00' immediately after the last character of the array.

This is only for compile-time known strings (aka literals) for easy C interop, if you make strings at runtime they won't have null terminator as a granted.
1 day ago
On Tuesday, 21 January 2025 at 05:54:48 UTC, evilrat wrote:
> On Monday, 20 January 2025 at 22:32:02 UTC, DLearner wrote:
>> It was because my understanding was that in certain situations the string construct did not just produce a character array - it also produced the (to me horrible) concept of adding a x'00' immediately after the last character of the array.
>
> This is only for compile-time known strings (aka literals) for easy C interop, if you make strings at runtime they won't have null terminator as a granted.

Suppose we have:
```
string str1 = "A" ~ "B";
```

Does that produce:
   str1 == x'41' x'42' x'00' or
        == x'41' x'00' x'42' x'00' or
        == x'41' x'00' x'42' x'00' x'00'?

And is str1.length == 2 or
                   == 3 or
                   == 4?

1 day ago

On Tuesday, 21 January 2025 at 09:34:29 UTC, DLearner wrote:

>

On Tuesday, 21 January 2025 at 05:54:48 UTC, evilrat wrote:

>

On Monday, 20 January 2025 at 22:32:02 UTC, DLearner wrote:

>

It was because my understanding was that in certain situations the string construct did not just produce a character array - it also produced the (to me horrible) concept of adding a x'00' immediately after the last character of the array.

This is only for compile-time known strings (aka literals) for easy C interop, if you make strings at runtime they won't have null terminator as a granted.

Suppose we have:

string str1 = "A" ~ "B";

Does that produce:
str1 == x'41' x'42' x'00' or
== x'41' x'00' x'42' x'00' or
== x'41' x'00' x'42' x'00' x'00'?

And is str1.length == 2 or
== 3 or
== 4?

In this example it definitely should be length == 2, if it is not then it is a bug.

It should only add null terminator AFTER the end of complete string, but it is technically not a part of that string.
You know, accessing slice memory beyond its length is unsafe, you should really never do this unless you are 100% know what exactly are you doing.

Look, here is why it does that - in C it is basically a convention that all strings is null terminated because this is how standard library works and so everyone else has to follow.
D gives you a favor by doing this automatically without the need of putting string greeting = "hello\0" or "hello " ~ "world" ~ '\0' everywhere in your code.

I hope this is now simple enough to understand.

19 hours ago
On Tuesday, 21 January 2025 at 09:34:29 UTC, DLearner wrote:
> Suppose we have:
> ```
> string str1 = "A" ~ "B";
> ```
>
> Does that produce:
>    str1 == x'41' x'42' x'00' or
>         == x'41' x'00' x'42' x'00' or
>         == x'41' x'00' x'42' x'00' x'00'?
>
> And is str1.length == 2 or
>                    == 3 or
>                    == 4?

It produces

    str1 == x'41' x'42'

...and then directly after str1 in the binary, there is an additional byte of storage that contains x'00'.
19 hours ago
On Tuesday, 21 January 2025 at 09:34:29 UTC, DLearner wrote:
> ...
> Suppose we have:
> ```
> string str1 = "A" ~ "B";
> ```
>
> Does that produce:
>    str1 == x'41' x'42' x'00' or
>         == x'41' x'00' x'42' x'00' or
>         == x'41' x'00' x'42' x'00' x'00'?
>
> And is str1.length == 2 or
>                    == 3 or
>                    == 4?

void main() {
  string str1 = "A" ~ "B";
  static string s =  "CD";
}

.L.str:
        .asciz  "AB"

immutable(char)[] example.main().s:
        .quad   2
        .quad   .L.str.1

.L.str.1:
        .asciz  "CD"

LDC (GDC seems pretty close).

https://godbolt.org/z/hjn3qKE19

Matheus.