May 24, 2022

On 5/24/22 10:06 PM, frame wrote:

>

Sorry, this was not affront, it was meant as my POV that you may have problems to get my problem because I have (as usually) forgot to make this more visible that some code was truncated.

OK, sorry to read into that ;)

>

I tried your suggestion, as replied to Adam - the symbol is unique and it shows that correct location. It's not different from the error message.

Just to be pedantic, you tried that call in the exact place the assert is failing to compile? D can be weird/surprising about name lookups.

>

However, this error has nothing to do with assert(). In fact the compiler allows nothing than invocation or this error will be triggered. Even that fails:

The compiler is treating fun not as a function pointer, but as a function. However, the type looks correct to me. I tried a simple example on run.dlang.io, even with multiple modules, and seems to work as expected.

>
// same error:
auto test = cast(void*)fun;

try:

pragma(msg, typeof(fun));

If I do:

extern(C) void foo(string) {}

pragma(msg, typeof(foo));
pragma(msg, typeof(&foo));

I get:

extern (C) void(string param)
extern (C) void function(string param)

The first is a function (yes, they have a type), and the latter is a function pointer.

So that might give a clue whether the compiler thinks fun is a function or a function pointer. D should never call a function pointer without parentheses.

If you get the latter, yet your assert fails, then that is most certainly a compiler bug. Again, important that you do this in the exact place the assert fails to ensure the same name lookup situation.

-Steve

May 25, 2022

On Wednesday, 25 May 2022 at 02:42:26 UTC, Steven Schveighoffer wrote:

>

Just to be pedantic, you tried that call in the exact place the assert is failing to compile? D can be weird/surprising about name lookups.

Yes, of course ;-)

>

try:

pragma(msg, typeof(fun));

Outputs:

extern (C) void function(...)
>

If I do:

extern(C) void foo(string) {}

pragma(msg, typeof(foo));
pragma(msg, typeof(&foo));

I get:

extern (C) void(string param)
extern (C) void function(string param)

The first is a function (yes, they have a type), and the latter is a function pointer.

But the compiler would complain if I call it as a type? And how could it call it later without an address to it - this works.

>

D should never call a function pointer without parentheses.

I'm very good in finding weird bugs ;-) Unfortunately, I cannot make an example. I already tried some changes/simplifications but cannot reproduce it outside the project.

But how can I help the compiler to use it as correct type? On invocation with arguments all works fine, but checking if the pointer is not null fails. It not even works with an assignment. Could some static if() maybe help or some asm trick?

May 24, 2022

On 5/24/22 11:14 PM, frame wrote:

>

On Wednesday, 25 May 2022 at 02:42:26 UTC, Steven Schveighoffer wrote:

> >

try:

pragma(msg, typeof(fun));

Outputs:

extern (C) void function(...)

OK, so it's a function pointer.

>

But the compiler would complain if I call it as a type? And how could it call it later without an address to it - this works.

You don't need an address to call it. The compiler shouldn't complain at all, nor should it decide to think you are calling it without parentheses.

> >

D should never call a function pointer without parentheses.

I'm very good in finding weird bugs ;-) Unfortunately, I cannot make an example. I already tried some changes/simplifications but cannot reproduce it outside the project.

I have encountered bugs like this (which disappear with seemingly unrelated removals). They are hard to deal with.

Have you tried dustmite? It can reduce D code down automatically to a smaller example, but be warned that if you get the condition wrong, and your code base is huge, it can take hours/days to whittle down to something that isn't what you want.

You can file a bug without a full example, just note that you have verified via the pragma(msg) statement above that the symbol is indeed a function pointer, and that compiler is trying to call it without explicit parentheses.

However, without a complete example, it's going to be hard to find/fix.

>

But how can I help the compiler to use it as correct type? On invocation with arguments all works fine, but checking if the pointer is not null fails. It not even works with an assignment. Could some static if() maybe help or some asm trick?

This is a compiler bug, at least I think so. Since the compiler is misbehaving, it's not clear how to make it behave.

-Steve

May 25, 2022

On Wednesday, 25 May 2022 at 03:41:17 UTC, Steven Schveighoffer wrote:

>

This is a compiler bug, at least I think so. Since the compiler is misbehaving, it's not clear how to make it behave.

-Steve

Well, ok, it's not my top priority and dustmite seems to run better on Unix - which I need to port anyway some time but not now.

But it must be possible to check if the function pointer is valid in Assembler? But I'm not familiar with asm to do it correctly - I would be very appreciative if someone could post an example how to do it in D.

So far, thank you for your time.

May 25, 2022

On 5/25/22 12:16 AM, frame wrote:

>

On Wednesday, 25 May 2022 at 03:41:17 UTC, Steven Schveighoffer wrote:

>

This is a compiler bug, at least I think so. Since the compiler is misbehaving, it's not clear how to make it behave.

-Steve

Well, ok, it's not my top priority and dustmite seems to run better on Unix - which I need to port anyway some time but not now.

But it must be possible to check if the function pointer is valid in Assembler? But I'm not familiar with asm to do it correctly - I would be very appreciative if someone could post an example how to do it in D.

So far, thank you for your time.

Well, you can possibly work around the type system, but I don't know what the compiler thinks you have there.

assert(*(cast(void**)&fun) !is null);

-Steve

May 25, 2022

On Wednesday, 25 May 2022 at 04:34:43 UTC, Steven Schveighoffer wrote:

>

Well, you can possibly work around the type system, but I don't know what the compiler thinks you have there.

This really bothers me and I put this test cases:

static if (isSomeFunction!fun) pragma(msg,...)
static if (isFunctionPointer!fun) pragma(msg,...)
static if (isCallable!fun) pragma(msg,...)

It output mostly true except in one case where the compiler really sees a function, not a pointer.

Thanks, now the difference is clear to me, Adam was right. I guess I have forgotten some version-switch somewhere and it tries to compile none-suitable code which will be never used in runtime at this point.

This would have been more visible if the compiler just says: "function cannot be compared against null, only function pointer". That function vs function pointer is too subtle.

May 25, 2022

On 5/25/22 1:40 AM, frame wrote:

>

This would have been more visible if the compiler just says: "function cannot be compared against null, only function pointer". That function vs function pointer is too subtle.

It's a case where the compiler can't divine what you were thinking when you wrote that code ;)

remember that the expression fun where fun is a function, and not a function pointer, is the equivalent of fun().

It can't figure out that you really thought fun was a function pointer, maybe it thinks that you are missing an overload? Maybe fun actually is a no-arg function, and the result isn't comparable against null (or maybe it is, and it compiles and does something completely different!).

But I'm glad you discovered the issue.

-Steve

May 25, 2022

On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote:

>

It's a case where the compiler can't divine what you were thinking when you wrote that code ;)

I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or assert() then it could at least suggest a pointer or ask: are you dumb? ;-)

May 25, 2022

On Wednesday, 25 May 2022 at 06:04:10 UTC, frame wrote:

>

On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote:

>

It's a case where the compiler can't divine what you were thinking when you wrote that code ;)

I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or assert() then it could at least suggest a pointer or ask: are you dumb? ;-)

As suggested by others, the reduction is not correct, you have stripped too muchbecause this compiles just fine:

a.d:

alias F = void function(int);
F f;

static this()
{
    assert(!f);
    assert(f is null);
}

b.d:

import a;

static this()
{
    assert(!f);
    assert(f is null);
}
$ dmd a.d b.d -main
$ echo $?
$ 0
May 25, 2022

On 5/25/22 6:55 AM, user1234 wrote:

>

On Wednesday, 25 May 2022 at 06:04:10 UTC, frame wrote:

>

On Wednesday, 25 May 2022 at 05:56:28 UTC, Steven Schveighoffer wrote:

>

It's a case where the compiler can't divine what you were thinking when you wrote that code ;)

I see not in all cases but in mine. If the compiler sees the function isn't callable without arguments and it is inside an if-statement or assert() then it could at least suggest a pointer or ask: are you dumb? ;-)

As suggested by others, the reduction is not correct, you have stripped too muchbecause this compiles just fine:

Yes, he acknowledged that too much was stripped. I also verified similar code works.

But the real problem was something else. He is saying in this message "why doesn't the compiler recognize that in comparing a function to null, I really wanted to compare a function pointer to null", but I don't see how the compiler can make that leap.

Often times, I wish the compiler could just read what I was thinking when I wrote the code, so it could give me thought-contextual errors but alas, it can't.

-Steve