I'm trying to export some C++ code in a C project...
Actually I'm stuck with the following problem:
_CreateToolhelp32Snapshot fnCreateToolhelp32Snapshot = (_CreateToolhelp32Snapshot) GetProcAddress(GetModuleHandleA(L"kernel32"), "CreateToolhelp32Snapshot");
_Thread32First fnThread32First = (_Thread32First) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32First");
_Thread32Next fnThread32Next = (_Thread32Next) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32Next");
I'm saving the memory address of the three functions ("CreateToolhelp32Snapshot", "Thread32First" and "Thread32First") in three objects in C programming... I'm compiling with mingw under Ubuntu 13.04 and I get this error:
(row 1): error: initializer element is not constant
(row 2): error: initializer element is not constant
(row 3): error: initializer element is not constant
I know that in C the address function are not considered as constant values, but will be very helpful find the way to resolve this constraint...
Thanks in advance for any suggestion...
You must be using global variables. Use an initialize function to set those values, before using it elsewhere. In standard c, you cannot execute code (like calling GetProcAddress function) before entering main.
_CreateToolhelp32Snapshot fnCreateToolhelp32Snapshot;
_Thread32First fnThread32First;
_Thread32Next fnThread32Next;
void initialize()
{
fnCreateToolhelp32Snapshot = (_CreateToolhelp32Snapshot) GetProcAddress(GetModuleHandleA(L"kernel32"), "CreateToolhelp32Snapshot");
fnThread32First = (_Thread32First) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32First");
fnThread32Next = (_Thread32Next) GetProcAddress(GetModuleHandleW(L"kernel32"), "Thread32Next");
}
int main()
{
initialize();
...
}
Related
Is there a way to conditionally add arguments to a constructor? I'd also like to know what this type of construction is called so I can search it myself.
I'm creating a boost::process::child using a constructor where I can pass any properties and things are mostly working great:
m_proc = new boost::process::child(
m_context,
boost::process::exe = m_config.exe,
boost::process::args = m_config.args,
boost::process::env = m_config.Environment,
boost::process::start_dir = m_config.WorkingDirectory,
boost::process::std_out > m_stdout_pipe,
boost::process::std_err > m_stderr_pipe,
boost::process::on_exit = [this](int i, auto e){OnProcExit(i, e);},
boost::process::extend::on_setup = [this](auto&){OnProcSetup();},
boost::process::extend::on_success = [this](auto&){OnProcSuccess();},
boost::process::extend::on_error = [this](auto&, auto ec){OnProcError(ec);}
);
UNTIL I call ls with no arguments. Then it returns
/usr/bin/ls: cannot access '': No such file or directory
Process Exited (code:2)
If m_config.args is empty, I want to avoid passing it. I tried:
m_proc = new boost::process::child(
...
boost::process::exe = m_config.exe,
m_config.args.empty() ? (void) : (boost::process::args = m_config.args),
...
);
but that gives:
error: expected primary-expression before ‘void’
I tried:
m_proc = new boost::process::child(
...
boost::process::exe = m_config.exe,
boost::process::args = m_config.args.empty() ? {} : m_config.args,
...
But that gives:
initializer list cannot be used on the right hand side of operator ?
error: expected primary-expression before ‘{’ token
I understand that for this particular case, I could combine exe and args to make a cmd, but I'd also like to conditionally add other arguments like boost::process::shell or boost::process::stdin.
If I need to call different constructor code for every set of options, I would need to write N! calls to constructors where N is the number of options and that grows fast.
This is ugly.
C++ isn't python, there isn't any named parameters in C++, so this solution makes use of global variables (boost::process::args) which are fundamentally not thread safe and prone to usage errors as you experienced.
In the boost documentation they state you don't need to use the global vars, so you can directly use the your config members here:
m_proc = new boost::process::child(
m_context,
m_config.exe,
m_config.args,
m_config.Environment,
[...]
By the way, the error you're reporting isn't due to a bad empty list passing (you can have m_config.args = {}) but probably to a wrong command argument list creation (if the list is empty, the boost::process::child code should create an non-empty string for the process's argument list, containing the executable name as the first argument).
The error you are reporting:
/usr/bin/ls: cannot access '': No such file or directory
is likely due to the wrong argument list being generated by boost and it's not due to your (empty) args array.
So I would put a debug breakpoint on the Popen syscall here and walk backward until I figure out what went wrong in building the argument string.
Using a global variable like a parameter here is syntax candy, but it means operator overloading to an unspecified object (as stated in the documentation), so you actually don't know what's going on here (a = b when a is unknown can be anything in C++, like a crazy making b set to the value of a as in T& operator =(T & b) { b = *this; return *this; }). You'll need to debug what's going on here to figure out what is happening. As a short advice, try to avoid using undefined object if it's not required and unclear, and stick to usual C++ practices.
I am using C++ in Visual Studio Code. When I want to initialise a variable I cannot initialise it with {} (e.g., int x {0};). Instead, I have to use () (e.g., int x (0);).
The error I get when using {} is "error: expected ';' at end of declaration" Although I have put ; at the end of declaration.
I'm using clang 11.0.0 as the compiler. Is it related to the compiler?
The code runs through the terminal by ./filename command. However, it gives errors when running by coderunner extension in VSCode.
In order to initialize a variable with {} you must say it is = {}.
Like this:
int x = {3}; //you wouldn't really do this for simple variable though I don't think since you can just say int x = 3;
//or if you are making a custom object you might say:
MyObject object = {"apples", 3, "red"};
// to set the variables inside the object. in the order they are declared.
I hope this answers your question!
I was porting some legacy code to VS 2015 when this compiler error halted the build:
error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member
Going to the corresponding file and line, I saw this:
Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
mgr->SetSymm(...
GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:
class Manager {
...
bool GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
....
};
class OptDlg {
...
void GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}
Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...
C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:
&OptDlg::GetFullModel // Standard-compliant
vs
OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems
vs
dlg.GetFullModel // ?
Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?
&OptDlg::GetFullModel // Standard-compliant
If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:
mgr->SetFullModel(dlg.GetFullModel());
if (dlg.GetFullModel())
mgr->SetSymm(...
Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.
Is this just another one of those VS 6 "extensions"?
It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.
It strongly looks to me like someone mis-typed dlg.GetFullModel() (which would call the function), not that they were trying to get a member function pointer.
Presumably the legacy compiler let it slide, taking the address of the function without using & and converting the non-null function pointer to bool (with value true) to pass into the set function.
I'm trying to iterator over the predecessors of a basic block and I'm getting using the following code:
for (::llvm::PredIterator PI = pred_begin(post_block); PI != pred_end(post_block); PI++)
{
::llvm::BasicBlock *pred = *PI;
if (pred != exec_block)
{ ...
In the line with the if statement, I'm getting the following error:
In instantiation of ‘llvm::PredIterator<Ptr, USE_iterator>::reference llvm::PredIterator<Ptr, USE_iterator>::operator*() const [with Ptr = llvm::BasicBlock; USE_iterator = llvm::Value::use_iterator_impl<llvm::Use>; llvm::PredIterator<Ptr, USE_iterator>::reference = llvm::BasicBlock*]’:LLVMTC.cpp:1489:31:
required from here /usr/local/include/llvm/Support/CFG.h:56:5: error: ‘const class llvm::Value::use_iterator_impl<llvm::Use>’ has no member named ‘atEnd’
assert(!It.atEnd() && "pred_iterator out of range!");
Does anyone have any ideas what might be causing this problem? I'm basing my code off of: http://llvm.org/docs/ProgrammersManual.html#iterating-over-predecessors-successors-of-blocks.
Thanks!
First it's important to address the difference between your approach and the one in the example you're referencing.
In the example, they're define an instance of the pred_iterator type, rather than the PredIterator class you've used, which is defined as
typedef PredIterator<BasicBlock, Value::user_iterator> pred_iterator
and then using the calling pred_begin which returns an instance of pred_iterator(BB) where BB is the basic block you pass.
In your case, you're creating an instance of the PredIterator class and assigning it to the BB pointer, then attempting to dereference upon which it hits this assert:
inline reference operator*() const {
assert(!It.atEnd() && "pred_iterator out of range!");
return cast<TerminatorInst>(*It)->getParent();
}
As an initial solution it might be helpful to try and completely mimic the method used by the example, and then if you still need to use your method, try and diagnose the problem by observing how the typing for PredIterator is defined.
I've been looking though the svn history, Since LLVM 3.5, CFG.h has been moved from include/llvm/Support to include/llvm/IR. So you may want to use the following
#include "llvm/IR/CFG.h"
instead of
#include "llvm/Support/CFG.h"
In the C language, in order to initialize a static local variable to a value unknown during compilation, I would normally do something like this (for example):
void func()
{
static int var = INVALID_VALUE;
if (var == INVALID_VALUE)
var = some_other_func();
...
}
In the C++ language, I can simply do:
void func()
{
static int i = some_other_func();
...
}
The only way (that I can think of) for a C++ compiler to resolve it properly, is by replacing this code with a mechanism similar to the C example above.
But how would the compiler determine a "proper" invalid value? Or is there another way which I haven't taken into consideration?
Thanks
Clarification:
INVALID_VALUE is a value which function some_other_func never returns.
It is used in order to ensure that this function is never invoked more than once.
The compiler will not generate code to do it based on its value but on a thread safe flag that ensure that the code is only executed once.
Something like that:
void func()
{
static int i;
static bool i_initialized;
if (!i_initialized) {
i = some_other_func();
i_initialized = true;
}
}
Except that generally it is not a bool but a thread safe way of testing it.
According to code seen by disassembling and debugging the g++ compiled code, there is a hidden variable that is initialized to 0 and when the initialization is run it is set to 1.
So the next time the initialization code isn't executed.