I basically have the following lines of code
void func1(size_t sz1)
{
double arr[sz1];
}
When I use the Microsoft Visual C++ 2019 (C) Compiler, error C2057 is thrown. When I use the MinGW64 Compiler (C), I don't get an error and the code works as expected. Does the MinGW64 Compiler automatically use mallaoc or why don't I get an error with this Compiler too? Furthermore, do I have to expect any troubles when using the lines of code above instead of malloc?
Well looking at c++ array - expression must have a constant value, it seems like g++ has this feature (so likely mingw also uses this). It seems that the compiler will alloc under the hood, but the problem becomes ofc that your code is not portable across compilers.
Related
vscode default c syntax checker seems that c standard used not high (maybe c99 or lower)
like the example following:
array ellipsis is available in c11 , actually it can compiled successfully if specified flag with "std=c11"
but vscode still seem it as a syntax error and underline it.
compiler is gcc rather than clang
have some way to fix it?
I am trying to compile a C source code to a machine code using an ubunto terminal
My tutor instruction was to use the following command:
running clang myprogramm.c -std=c11
Why shall I use the keyword -std=c11 and what is the difference to using just
clang myprogramm.c
Using std= options is required by your tutor (I'm divinig her motives, I'm particularly good at this!) because she wants to make sure you stay away from all those nifty Clang features that turn the accepted language from C to A LANGUAGE SUPERFICIALLY LOOKING LIKE C BUT ACTUALLY A DIFFERENT LANGUAGE NOT SUPPORTED BY OTHER C COMPILERS.
That is more than just additional library functions. It include syntax changes that break the grammar of Standard C, as defined by ISO. A grasshopper should not use these while learning. Using -std=c11 makes sure Clang either warns about or even rejects, with an error, such constructs.
When to specify the standard? Whenever you use the compiler. It is never a good idea to let the compiler just use whatever it wants.
If someone tries to use a compiler that is too old, then they will get a warning or error, and they will understand why the compile fails.
If a code contributor (maybe even yourself!) tries to add code using features that are too new, their code will be rejected. That's very important if you intend to keep compatibility with an older standard.
By explicitly stating the standard, using new features or extensions are a choice and don't happen by accident.
I want to get rid of all implicit-function-declaration warnings in my codebase. But there is a problem because some functions are
programmed into the microcontroller ROM at the factory and during linking a linker script provides only the function address. These functions are called by code in the SDK.
During compilation gcc of course emits the warning implicit-function-declaration. How can I get rid of this warning?
To be clear I understand why the warning is there and what does it mean. But in this particular case the developers of SDK guarantee that the code will work with implicit rules (i.e. implicit function takes only ints and returns an int). So this warning is a false positive.
This is gnu-C-99 only, no c++.
Ideas:
Guess the argument types, write a prototype in a header and include that?
Tell gcc to treat such functions as false positive with some gcc attribute?
You can either create a prototype function in a header, or suppress the warnings with the following:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-function-declaration"
/* line where GCC complains about implicit function declaration */
#pragma GCC diagnostic pop
Write a small program that generates a header file romfunctions.h from the linker script, with a line like this
int rom_function();
for each symbol defined by the ROM. Run this program from your Makefiles. Change all of the files that use these functions to include romfunctions.h. This way, if the linker script changes, you don't have to update the header file by hand.
Because most of my programming expertise was acquired by self-study, I intentionally have become somewhat anal about resolving non-fatal warnings, specifically to avoid picking up bad coding habits. But, this has revealed to me that such bad coding habits are quite common, even from formally trained programmers. In particular, for someone like me who is also anal about NOT using MS Windows, my self-study of so-called platform-independent code such as OpenGL and Vulkan has revealed a WORLD of bad coding habits, particularly as I examine code written assuming the student was using Visual Studio and a Windows C/C++ compiler.
Recently, I encountered NUMEROUS non-fatal warnings as I designed an Ubuntu Qt Console implementation of an online example of how to use SPIR-V shaders with OpenGL. I finally threw in the towel and added the following lines to my qmake .PRO file to get rid of the non-fatal-warnings (after, first, studying each one and convincing myself it could be safely ignored) :
QMAKE_CFLAGS += -Wno-implicit-function-declaration
-Wno-address-of-packed-member
[Completely written due to commends]
You are compiling the vendor SDK with your own code. This is not typically what you want to do.
What you do is you build their SDK files with gcc -c -Wno-implicit-function-declaration and and your own files with gcc -c or possibly gcc -o output all-your-c-files all-their-o-files.
C does not require that declarations be prototypes, so you can get rid of the problem (which should be a hard error, not a warning, since implicit declarations are not valid C) by using a non-prototype declaration, which requires only knowing the return type. For example:
int foo();
Since "implicit declarations" were historically treated as returning int, you can simply use int for all of them.
If you are using C program, use
#include <stdio.h>
I'm having the following issue:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main() {
HANDLE handle;
DWORD dw;
handle = LoadLibrary("C:\\Folder\\mydll.dll");
dw = GetLastError();
printf("Loading Library: %d", dw);
FreeLibrary(handle);
return 0;
}
When compiling this with Netbeans/MinGW, everything works fine, the DLL is loaded and the output is "Loading Library: 0".
But when compiling the exact same code on the exact same machine with Visual C++ 2008 Express, I get the infamous 126 error: "Loading Library: 126".
The DLL is obviously existent at the specified location and loading it works as well - when I'm using Netbeans with MinGW. But why doesn't it work when using Visual C++?
This is only sample code to outline my problem. It's part of a much larger project which works completely fine when compiled with Netbeans/MinGW, but which doesn't load the DLLs when compiled with Visual C++...
Thanks for all answers!
Because your answer is incomplete and misses the real problem, I'll elaborate here.
You are compiling the MSVS version with UNICODE defined, which makes stuff like LoadLibrary be defined as a macro to LoadLibraryW, which takes a const wchar_t* argument. In contrast, when compiling with GCC, you don't define that, and it works.
The reason the UNICODE version actually compiles is somewhat a bug/feature in MSVS that allows you to pass a char* to a wchar_t* without any message (you did turn on warnings, didn't you?). This results in some misinterpreted string being passed to the Win32 API function, which fails to locate the garbled filename.
This is why I always call the *W versions of functions directly, and don't bother with all the funny UNICODE stuff.
I've found the solution by now. FreeLibrary("mystringpath.dll") apparently doesn't work. But when I call the function with LPCWSTR, it works. So:
handle = LoadLibrary("C:\\Folder\\mydll.dll");
Produces ERROR_MOD_NOT_FOUND when compiled with Visual C++, but works when compiled with MinGW.
But the following works when compiled with Visual C++:
LPCWSTR path = L"C:\\Folder\\mydll.dll";
handle = LoadLibrary(path);
And returns ERROR_SUCCESS (0).
So all the allegedly missing dlls pointed out by dependency walker really weren't the problem.
The funny thing, though, is that using the fix in Netbeans/MinGW results in the Netbeans .exe returning 126. And when compiling, gcc complains about passing an argument from an imcompatible pointer type.
So the first code works only for MinGW, the second only for Visual C++...
Upon further research, I've realized that this fix is unnecessary. Apparently, the problem was that my Visual C++ project used the Unicode character set by default. After I changed it into the Multibyte Character Set in the project properties, the code pasted in the original question is working fine in Visual C++ as well...
Compiler: Microsoft Visual C++ 2010 Express, SP1
Project Property: C/C++ Advance Compile As: Compile as C Code (/TC)
Message:
error C2099: initializer is not a constant
Simple Test Case Showing Error:
typedef struct
{
char *stringP;
int lino;
} foo_t;
#define bad {static foo_t foo ={__FILE__,__LINE__};}
#define good {static foo_t foo ={"filename",10};}
int main()
{
bad; // error C2099: initializer is not a constant
good; // no error
return 0;
}
This generates a C2099 error. This code compiles & links correctly under gcc but not Visual C++ 2010 Express (compile as C Code - i.e. /TC option).
Your code compiles well on my system (MS Visual Studio 2005).
You can preprocess your code to try finding the problem manually:
cl your_file.c /E > stuff.c
This generates a preprocessed file (you probably have to supply a whole lot more command-line options; you can copy-paste them from the project's Property Pages).
cl stuff.c
This should reproduce the problem. Then try looking at the code in stuff.c; if you don't see the problem immediately, try tweaking it (e.g. replacing complex things with 0) - this should hint on the problem.
(Since your system is much newer than mine, some details may be different, e.g. maybe the compiler on your system is called something other than cl, but the idea will probably work)
For some reason the Microsoft C compiler does not recognize the __LINE__ preprocessor macro as a constant (presumably because it changes from line to line?), so you can't use it to initialize a structure member.
Generating the preprocessed .i file doesn't really help because it generates legal code that compiles just fine after __LINE__ has been replaced with a constant. Apparently, the C compiler is not trying to compile this same preprocessed output.
You should be able to use
foo.lino = __LINE__;
later without any problems. This seems to be a gripe from the Microsoft C compiler. Other C compilers I've used don't seem to have any problems with this use of __LINE__.
The only workaround I've been able to find is to compile the file as C++ code (/Tp).
__LINE__ macro is not recognized as constant by MSVC compiler when "Edit & Continue" debug database mode is enabled. If you don't care about "Edit & Continue", you can switch to another database mode and the problem should disappear.