Sequence of Raku program compilation and execution (maybe nested compile phases?) - compilation

The following program correctly fails to compile:
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';
Specifically, line 3 causes a compilation error (with a ===SORRY!=== error message); this error occurs before line 2 is executed, so the type mismatch within &f is never reached.
But when, specifically, does this error occur? I thought it occurred during the CHECK phase, but was surprised to notice that raku -c does not generate a compile error; it reports Syntax OK.
To dig into this a bit more, I added logging code to the snippet above:
BEGIN note 'begin';
CHECK note 'check';
INIT note 'init';
END note 'end';
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';
Running this revised code with raku -c prints "begin\n check\n Syntax OK"; running it with raku prints "begin\n check\n ===SORRY!===" (and the rest of the error message).
If I remove the say f 'foo' line (and thus the compile error), raku -c still prints "begin\n check\n Syntax OK" but raku prints "begin\n check\n init\n Type check failed… \n end" (again omitting the body of the error message).
What's going on here? Does the compile error that generated the ===SORRY!=== occur some time between CHECK and INIT (is there any such time?)? Or does raku -c not actually "run BEGIN and CHECK blocks" as raku --help indicates? Or something else?
Relatedly: how, if at all, is any of this connected to the idea of "nested compile times"? Does the execution of this code involve any nested compile times, or does that only occur when using modules? Is there any way to note/log separate compile phases (maybe with correctly placed BEGIN blocks?) or is that something that isn't exposed?

The SORRY message is a side-effect of the static optimizer. Observe the difference in behaviour between:
$ raku -e 'sub foo(Int $a) { }; foo "foo"'
===SORRY!=== Error while compiling -e
Calling foo(Str) will never work with declared signature (Int $a)
and:
$ raku --optimize=off -e 'sub foo(Int $a) { }; foo "foo"'
Type check failed in binding to parameter '$a'; expected Int but got Str ("foo")
in sub foo at -e line 1
which happens somewhere between CHECK and INIT time, unless it has been disabled. Note that disabling the static optimizer makes it a runtime error.

Related

Why is #include breaking global variables?

I have a simple .ahk file which reloads the currently running script any time I press Esc.
; reload-hotkey.ahk
Esc::Reload ; reload script with Esc
For some reason, importing this file causes global variables to stop working properly.
; test-file.ahk
#Include %A_ScriptDir%\reload-hotkey.ahk ; This line causes the problem
globalString := "Hello"
^q::
localString := "World"
MsgBox '%globalString% %localString' ; Output: ' World'
Return
If I remove my #include statement, the code works as expected.
; test-file-2.ahk
globalString := "Hello"
^q::
localString := "World"
MsgBox '%globalString% %localString%' ; Output: 'Hello World'
Return
This only happens if my included file includes a hotkey. If the function only includes methods or functions, my code will work as expected.
For reference, I am using AutoHotkey Unicode 32-bit 1.1.26.01.
Why would an #include statement cause global variables to not work properly?
Variable definitions must occur before any hotkey or hotstring definitions.
So put the variable definition above the include statement.
globalString := "Hello"
#Include %A_ScriptDir%\reload-hotkey.ahk ; This line causes the problem
For more information, see the Auto-execute Section in the Autohotkey documentation.

Lintering warning whereas compilation is ok

I have some variables defined in makefile.init:
MY_VARIABLE = some_value
In the preprocessor settings I have this -D switch:
-DUSE_MY_VAR=\"$(MY_VARIABLE)\"
And in a source file, I have this:
static const char* my_val = USE_MY_VAR;
So this my_val will get the value set in the makefile.init file.
It compiles just fine, but the indexer complains with a warning "Bad character sequence encountered: \". Is there a way to make it understand it or maybe make it ignore this specific variable?
Ok finally found something that make both compiler and indexer happy:
my -D switch becomes (removed the escaped quotes):
-DUSE_MY_VAR=$(MY_VARIABLE)
and in the source code (thanks to Expand macro inside string literal):
#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)
static const char* my_val = STRINGIFY(USE_MY_VAR);

GCC - display preprocessed value during preprocessing

Is there a way to make GCC display the value of some preprocessed value during preprocessing? In particular, if I run the equivalent of:
gcc input.c -E >/dev/null
Is there a way to obtain the actual value of an expanded macro? Consider this example:
#if defined(A)
#define B bar
#else
#define B foo
#endif
#define XSTR(x) STR(x)
#define STR(x) #x
int main() {
#pragma message "B is " XSTR(B)
#error DIE
B a = 2;
return 0;
}
I would like to find out that B is foo in this case.
In my actual setup, I do not have access to the entirely preprocessed file, and I cannot remove the -E flag.
Rationale: I have a complex file setup with lots of syntax errors due to incorrectly defined macros, and the fastest way to debug it would be to use this #pragma/#error combination to find out the actual value, stop compilation, manually fix it, and run GCC again to find out where the next error will occur.

risk of compile warning

I have mainly two kinds of compile warning:
1. implicit declaration of function
in a.c, it has char *foo(char *ptr1, char *ptr2), in b.c, some functions use this foo function without any declaration, and I found seems compiler will treat the function foo return value as integer, and even I can pass some variables less or more than foo function declaration
2. enumerated type mixed with another type
My target chip is ARM11, it seems that even I don't solve these two kinds of compile warning, my program can run without any issues, but I believe it must have some risk behind these. Can anyone give me some good example that these two kinds of compile warning can cause some unexpected issues?
Meanwhile, if these two warnings have potential risk, why c compiler allow these kinds warning happen but not set them to error directly? any story behind?
Implicit declaration. E.g. you have function: float foo(float a), which isn't declared when you call it. Implicit rules will create auto-declaration with following signature: int foo(double) (if passed argument is float). So value you pass will be converted to double, but foo expects float. The same with return - calling code expects int, but returned float. Values would be a complete mess.
enum mixed with other type. Enumerated type have list of values it could take. If you trying to assign numeric value to it, there is a chance that it isn't one of listed values; if later your code expects only specified range and presumes nothing else could be there - it could misbehave.
Simple example:
File: warn.c
#include <stdio.h>
double foo(double x)
{
return myid(x);
}
int
main (void)
{
double x = 1.0;
fprintf (stderr, "%lg == %lg\n", x, foo (x));
return 0;
}
File: foo.c
double
myid (double x)
{
return x;
}
Compile and run:
$ gcc warn.c foo.c -Wall
warn.c: In function ‘foo’:
warn.c:5: warning: implicit declaration of function ‘myfabs’
$ ./a.out
1 == 0
Old C standard (C90) had this strange "default int" rule and for compatibility it is supported even in latest compilers.

The program '[6096] lencod.exe' has exited with code 300 (0x12c)

The program '[6096] lencod.exe' has exited with code 300 (0x12c).
what does this mean? is there an error? i have a variable named mbBits->mb_total. is the arrow a syntax of some sort or is it just part of the variable name. i'm debugging the code which i downloaded but when i put the variables in the watch window it says "undefined variable 'mbBits' or something like that.
I also used this code to generate a text file
void next_macroblock(Macroblock *currMB)
{
FILE * pFile;
pFile = fopen ("myfile.txt","a");
fprintf (pFile, " \t %d \t | \n",mbBits->mb_total);
fclose (pFile);
}
but it says that FILE is unidentified and it also tells me to save the code in Unicode Format. I already tried doing that but more errors come out. heeeeeelp
You will need to at least include <stdio.h> to get the references to FILE to compile.
The main() function also probably has a non-void return value. The value returned is what is displayed in your message. Include a return(0); in each possible path to ensure that the value is set to 0 (indicating, by convention, no error) in the program.

Resources