Why is #include breaking global variables? - include

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.

Related

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

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.

What does it mean when Xcode returns (lldb) after scanf input?

I'm working through the book "C Programming Absolute Beginner's Guide to learn a little more about C so I can better understand what I need to do for an Arduino project. I'm using Xcode 12.4 on a Big Sur iMac because CodeBlocks, the IDE used in the book's examples, doesn't work on this computer.
In the chapter that covers scanf() when I run the sample program, Xcode returns (lldb) after my first input. Here's my simplified program that exhibits that return:
//
// main.c
// Chapter8ex1a
//
// Created by Kellidad on 3/25/21.
//
/* This program asks the user for some basic data and prints it on the screen to show
what was entered */
#include <stdio.h>
int main() {
// setup the variables that scanf will fill
char firstInitial;
char lastInitial;
printf("What letter does your first name begin with?\n");
scanf(" %c, &firstInitial");
printf("What letter does your last name begin with?\n");
scanf(" %c, &lastInitial");
printf("\nYour initials are %c.%c.", firstInitial, lastInitial);
return 0;
}
And here's what is displayed in the console:
What letter does your first name begin with?
L [followed by <Return>]
(lldb)
In addition, Xcode displays "Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)" at the first scanf() line.
Matt suggested it's a prompt waiting for something else, but if I repeat and enter another character I get this:
What letter does your first name begin with?
L <Enter>
(lldb) H <Enter>
error: 'H' is not a valid command.
(lldb)
Unfortunately, what I've found about (lldb) is meaningless to me. Can I make scanf() work in this example using Xcode or is there a better way for a beginner to accept characters from the keyboard?
Thanks!
The problem was the position of the " " in the scanf() - the function should read scanf(" %c", &firstInitial); not scanf(" %c, &firstInitial");

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);

Why does libncurses ui not display when capturing to Bash variable?

I've written a libcurses-based ascii ui that writes text to stdout when the program exits.
If I execute the program alone, like so...
> ./test
...the ui displays.
However, if I try to capture the program output to a Bash variable, like so...
> foo=$(./test)
...the ui does not display, however the Bash variable captures the expected output.
Does anyone know why this behavior is as such? Is there a way to get the ui to show up when trying to capture its stdout to a Bash variable?
The Code
#include <iostream>
#include <curses.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
WINDOW* pWindow = initscr();
keypad(pWindow, TRUE);
curs_set(0);
nodelay(pWindow, FALSE);
mvwprintw(pWindow, 5, 5, "hello, world!");
mvwprintw(pWindow, 6, 5, "hello, fold!");
mvwprintw(pWindow, 7, 5, "hello, toad!");
for (int i = 0; i < 5; ++i)
{
mvwprintw(pWindow, 5 + i, 1, "==>");
refresh();
usleep(500000);
mvwprintw(pWindow, 5 + i, 1, " ");
refresh();
}
endwin();
std::cout << "bar" << std::endl;
}
Simply because redirecting the std output (>, a=$(…)) just redirects the standard output – ncurses, on the other hand, directly talks to the terminal and displays characters, that never are part of stdout.
Short: it doesn't capture the output because there is none. Instead, ncurses programs directly talk to the underlying terminal.
Is there a way to get the ui to show up when trying to capture its stdout to a Bash variable?
I don't recommend that. Because you're mixing non-interactive usage (getting std output) and interactive, and that can't really go well in the end, but:
you can end your ncurses session and just use printf like any other C programmer. Then you'd actually be producing std output.
I'd much rather just add an option to my program that takes a file to which I write my output. Then the bash script could open that file after my program has run.
When you initialize curses using initscr, it will use the standard output for display. (You could use newterm to specify another output). So when you redirect the output of the program you will not see the user-interface.
Adapting your example,
#!/bin/bash
g++ -o test foo.c $(ncursesw6-config --cflags --libs)
foo=$(./test)
set >foo.log
and looking at what bash puts in $foo, I see the expected control characters which are written in the user interface, e.g.,
foo=$'\E[?1049h\E[1;40r\E(B\E[m\E[4l\E[?7h\E[?1h\E=\E[?25l\E[H\E[2J\E[6d ==> hello, world!\n\E[6Ghello, fold!\n\E[6Ghello, toad!\E[6;5H\r \r\n ==>\r \r\n ==>\r \r\n ==>\r\E[J \r\n ==>\r\E[J \E[40;1H\E[?12l\E[?25h\E[?1049l\r\E[?1l\E>bar'

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