When providing the wrong number of arguments to printf():
printf("%s", "foo", "bar");
or when by providing arguments of the wrong type:
printf("%d", "foo");
gcc is able to warn about these mistakes:
$ gcc -Wformat printf_too_many_arguments.c
printf_warnings.c: In function `main':
printf_warnings.c:5: warning: too many arguments for format
printf_warnings.c:5: warning: too many arguments for format
$ gcc -Wformat printf_argument_of_wrong_type.c
printf_warnings.c: In function `main':
printf_warnings.c:5: warning: format `%d' expects type `int', but argument 2 has type `char *'
printf_warnings.c:5: warning: format `%d' expects type `int', but argument 2 has type `char *'
How to get such warnings with Visual Studio 2005?
-- dave
I use cppcheck (http://cppcheck.sourceforge.net/) when working with Visual Studio 2005 which detects mismatches between the number of parameters provided to printf/wprintf and the number of parameters required.
Unfortunately it doesn't check the types match, but it's a start.
Unfortunately MSVC/Visual Studio does not support this.
See also __attribute__((format(printf, 1, 2))) for MSVC?
You will need additional software to do this. Take a look at PC-Lint (http://www.gimpel.com/). It can find these kinds of errors (and much more [potential] errors as well).
Related
I am trying to build a dll in C++ in which I use a C dll with prototypes like :
int __stdcall foo();.
When linking, the compiler outputs:
Warning: resolving _foo#0 by linking to _foo
Use --enable-stdcall-fixup to disable these warnings
so I added the option when linking, the command looks like:
g++ -std=c++0x -o fooLib.dll fooObj.o -lfooClib --enable-stdcall-fixup -shared
but seems like the g++ doesn't know this option:
g++.exe: error: unrecognized option '--enable-stdcall-fixup'
when I am adding only -enable-stdcall-fixup (one hyphen), it still shows the warnings (looks like has the option has no effect), and the ouput is kind weird:
g++ -std=c++0x -o fooLib.dll fooObj.o -lfooClib -enable-stdcall-fixup -shared
Warning: resolving _foo#0 by linking to _foo
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
ld.exe: warning: cannot find entry symbol nable-stdcall-fixup; defaulting to 679c1000
so does any body know what I am doing wrong ?
g++ --version
g++ (GCC) 4.6.1
Indeed, --enable-stdcall-fixup is not a g++ option. It's a linker option, and you can find it in the ld(1) manpage:
--enable-stdcall-fixup
--disable-stdcall-fixup
If the link finds a symbol that it cannot resolve, it will attempt
to do "fuzzy linking" by looking for another defined symbol that
differs only in the format of the symbol name (cdecl vs stdcall)
and will resolve that symbol by linking to the match. For example,
the undefined symbol "_foo" might be linked to the function
"_foo#12", or the undefined symbol "_bar#16" might be linked to the
function "_bar". When the linker does this, it prints a warning,
since it normally should have failed to link, but sometimes import
libraries generated from third-party dlls may need this feature to
be usable. If you specify --enable-stdcall-fixup, this feature is
fully enabled and warnings are not printed. If you specify
--disable-stdcall-fixup, this feature is disabled and such
mismatches are considered to be errors. [This option is specific
to the i386 PE targeted port of the linker]
gcc is able to recognize some common linker options and pass them on to ld. For example, gcc passes the -llibrary options used to link in library code directly to the linker, as well as an option -e which will be relevant below. Whenever this is the case, it's documented in the gcc(1) manpage.
As you've discovered, this is not the case with --enable-stdcall-fixup, so you'll need to explicitly pass it. In order to pass arbitrary options to the linker, gcc has -Wl. From gcc(1):
-Wl,option
Pass option as an option to the linker. [...]
So in your case, you would call
g++ -Wl,--enable-stdcall-fixup [...]
I don't have the version of the linker mentioned in the manpage, so it still comes up as an unrecognized option for me. But on your system, given that the linker is telling you to use the option, I can only assume it is the version that recognizes it.
As an aside, when you tried calling the option with only one dash, you ran into a red herring. You were actually invoking the -e gcc option that I mentioned above, with the option argument nable-stdcall-fixup. From gcc(1):
-e entry
--entry=entry
Specify that the program entry point is entry. The argument is
interpreted by the linker; the GNU linker accepts either a symbol
name or an address.
So you actually ended up passing an option to the linker saying that, when you execute your program, you want it to begin execution from a function named nable-stdcall-fixup instead of the usual main.
I'm currently writing a new frontend for LLVM, and I've come across a problem when using large arrays on the stack. Apparently the compiler inserts references to __chkstk in functions that have a large stack, which is fine, but results in a linker error:
lld-link: error: undefined symbol: __chkstk
I see the purpose of __chkstk, and I don't want to do workarounds, like implementing dummy functions, setting /Gs9999999... or any of the other workarounds I've seen on forum posts. Instead, I would like to actually just link to this function, wherever it may be. Actually, I've even removed my own code from the equation, and am just using clang and other llvm tools, and can show the following:
PS> cat hello.c
int main()
{
char buffer[10000000];
}
PS> clang -S -emit-llvm hello.c
PS> cat hello.ll ; ModuleID = 'hello.c'
source_filename = "hello.c"
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-pc-windows-msvc19.29.30038"
; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 #main() #0 {
%1 = alloca [10000000 x i8], align 16
ret i32 0
}
attributes #0 = { noinline nounwind optnone uwtable "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" "unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}
!0 = !{i32 1, !"wchar_size", i32 2}
!1 = !{i32 7, !"PIC Level", i32 2}
!2 = !{!"clang version 12.0.1"}
PS> llc -o hello.obj --filetype=obj hello.ll
PS> lld-link /out:hello.exe /entry:main hello.obj lld-link: error: undefined symbol: __chkstk
>>> referenced by hello.obj:(main)
Actually, I get the same error when I use link.exe instead of lld-link.
error LNK2001: unresolved external symbol __chkstk
When I compile directly to an executable, clang hello.c -o hello.exe, this works just fine, so I suppose that under the hood, clang is doing something special with the linker options, or maybe it's just preventing insertion of the __chkstk symbol in the first place? I would generally like to take the same approach as clang if I don't have a good reason not to, but this area of clang is opaque to me.
So my question then, is what lib files (or other linker options) is clang doing here? Or how do I otherwise include the header/lib file which contains __chkstk?
After a lot of back and forth, I've finally figured it out, in what I think is the correct way. I was using just Windows SDK, which is not enough to build on Windows, you also need Visual Studio, or at least just the Build Tools. So as part of my toolchain installation, I now install both of these, and use these parameters to the linker:
/defaultlib:C:\Program Files (x86)\Windows Kits\10\Lib\${sdkVersion}\ucrt\${targetDepth}\ucrt.lib
and add "msvcrt.lib" and "libcmt.lib", located in C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Tools\MSVC\${msvcVersion}\lib\
I do not distribute any of these files myself, rather, I just run the installers for Windows SDK and the MSVC Build Tools, and then expect the correct lib files to exist in those locations.
One good hint I got, was to look at the verbose output of the clang command, clang hello.c -o hello.exe -v which shows the full set of arguments being sent to the linker, and gives a good template to start from.
Elsewhere (here on SO, for example) and even my own memory tells me that #error will cause compilation to terminate, but if I compile this:
#ifndef FOO
# error "FOO not defined."
#endif
int main() {
return "exit now!!";
}
I get:
g++ -Wall -o /dev/null main.cpp
main.cpp:2:4: error: #error "FOO not defined."
# error "FOO not defined."
^~~~~
main.cpp: In function 'int main()':
main.cpp:8:10: error: invalid conversion from 'const char*' to 'int' [-fpermissive]
return "exit!!";
^~~~~~~~
This is for g++ versions 5.4.0 (Ubuntu 5.4.0-6ubuntu1~16.04.4 20160609) and 7.0.0 (built myself 20161128). (There is a similar question asked here about MS Visual Studio 2015.)
According to the GNU CPP manual:
The directive ‘#error’ causes the preprocessor to report a fatal error. The tokens forming the rest of the line following ‘#error’ are used as the error message.
So, perhaps I just don't know what a "fatal error" is. The gcc option -Wfatal-errors would imply that a fatal error is one that would cause compilation to terminate, but nothing in the manuals ever defines it (unless I missed it). An answer to this question, however, is a bit more guarded and says that:
[#error] renders the translation unit ill-formed (i.e., it causes compilation to fail)
which I don't read as saying the same thing as saying compilation terminates at that point.
So, is this behaviour of gcc correct?
"Error" and "fatal error" were not separate categories in gcc until fairly recently. People would say "fatal error" just to make sure you understood that the compilation would not produce the expected object file. "warning" and "error" were always separate, but that wasn't obvious to everyone. You might think a warning is a type of error if you weren't told otherwise.
I don't know whether there was ever a version of gcc that actually terminated immediately after the #error, but I doubt it. It's possible that in the era when cpp was actually a separate program, it would have terminated at the end of the preprocessing phase without calling the compiler proper; that would have resulted in less error messages. (But not when -pipe was used to run them simultaneously!)
You could report a bug against the cpp manual. It's using "fatal error" in a way that is no longer consistent with the use of the term in the rest of the gcc manual.
I have errornously forgotten to put the parameter List after the call to a function, and the gcc did not intercept (because he believes it is a TRUTH-value). Is there a gcc warning/error switch, which helps me to locate those places? example:
short function(short arg);
main() {
if (function) { // I wanted to write function(arg)
//do something
}
}
The Version of the gcc I am using is 3.2.1.
Looking at the GCC man page, it seems that what you need is -Waddress.
-Waddress
Warn about suspicious uses of memory addresses. These include using the address of a function in a conditional
expression, such as "void func(void); if (func)", and comparisons against the memory address of a string literal, such as
"if (x == "abc")". Such uses typically indicate a programmer error: the address of a function always evaluates to true,
so their use in a conditional usually indicate that the programmer forgot the parentheses in a function call; and
comparisons against string literals result in unspecified behavior and are not portable in C, so they usually indicate
that the programmer intended to use "strcmp". This warning is enabled by -Wall.
As stated there, you can enable this flag with -Wall too.
Use "-Wall" option with gcc. This option force gcc to show all kinds of warnings at compilation.
You may get following warning when you compile your code by 'gcc -Wall' command.
`function' undeclared (first use in this function)
I would like to compile a Fortran 90 (fixed format) library under Windows. However, I cannot understand the error of prepocessor variables.
Say the sample file is VF_TestPreprocessor.F:
program VF_TestPreprocessor
implicit Integer(A-Z)
Parameter (TestAlpha=22,TestBeta=TestGamma)
print *, TestBeta
end program VF_TestPreprocessor
Under Linux, I can use ifort VF_TestPreprocessor.F -DTestGamma=25 to compile, and run.
However, under windows, I cannot use ifort VF_TestPreprocessor.F /DTestGamma=25 to compile. The error message is error #6592: This symbol must be a defined parameter, an enumerator, or an argument of an inquiry function that evaluates to a compile-time constant. [TestGamma]. Could you help to analyse the error?
It looks like ifort doesn't run the preprocessor. I have no experience with ifort, but this page (the first hit in Google on ifort preprocessor) says that on Windows the preprocessor is only run on files ending in an extension of .fpp.
So, I guess there are (at least) two solutions:
Rename your files to end in .fpp;
invoke ifort with the /fpp switch.