GCC error: 'for' loop initial declaration used outside C99 mode - linux

I'm getting error: 'for' loop initial declaration used outside C99 mode when I try to compile with make. I found a wiki that says
Put -std=c99 in the compilation line: gcc -std=c99 foo.c -o foo
Problem is I don't know how to specify this in make. I opened Makefile, found CC = gcc and changed it to CC = gcc -std=c99 with no results. Any ideas?

Put CFLAGS=-std=c99 at the top of your Makefile.
To remove the error without using C99, you just need to declare your iterator variable at the top of the block the for loop is inside.
Instead of:
for (int i = 0; i < count; i++)
{
}
Use:
int i;
//other code
for (i = 0; i < count; i++)
{
}

NEW: i tried make CFLAGS=-std=c99,finally useful.
OLD:if you have added CFLAGS=-std=c99 into MakeFile,and got error too.
maybe use make clean before make is a good idea.

Related

How do I disable MSVC warnings from headers included with quotes instead of angle brackets when using /analyze?

I am trying to add the /analyze flag to cl.
I am getting a warnings from external headers I #include "...", even though I am using /analyze:external- and /external:I ....
What am I doing wrong?
Example project:
main.cpp
#include "external.h"
// #include <external.h> <- hides external's warnings
int main() {
int shadowed = 0;
{ float shadowed = 0; }
return 0;
}
external.h
void something() {
int external_shadowed = 0;
{ float external_shadowed = 0; }
}
I run this command from the VS developer prompt:
cl /EHsc /analyze /analyze:external- /I include /external:I external /external:W0 main.cpp
And I proceed to get warnings from both files.
It seems MSVC only considers /external:I directories to actually be external if they are included with <> instead of "". This is not documented anywhere, and I would consider it a bug with the compiler. Third-party libraries should not necessarily always be included with <>.
More info and possibly updates in the future here: https://developercommunity.visualstudio.com/t/analyze:external--and-external:I-flags/1688240
I have not tested myself, but according to Hwi-sung Im [MSFT], <> and "" now act the same w.r.t /external:I in Visual Studio 2022 17.0.

macosx thread explicitly marked deleted

I'm building an application with C++11 threads, but I can't seem to get it to work with clang++ on MacOSX 10.9. Here is the simplest example I can find that causes the issues:
#include <thread>
#include <iostream>
class Functor {
public:
Functor() = default;
Functor (const Functor& ) = delete;
void execute () {
std::cerr << "running in thread\n";
}
};
int main (int argc, char* argv[])
{
Functor functor;
std::thread thread (&Functor::execute, std::ref(functor));
thread.join();
}
This compiles and runs fine on Arch Linux using g++ (version 4.9.2) with the following command-line:
$ g++ -std=c++11 -Wall -pthread test_thread.cpp -o test_thread
It also compiles and runs fine using clang++ (version 3.5.0, also on Arch Linux):
$ clang++ -std=c++11 -Wall -pthread test_thread.cpp -o test_thread
But fails on MacOSX 10.9.5, using XCode 6.1 (regardless of whether I include the -stdlib=libc++ option):
$ clang++ -std=c++11 -Wall -pthread test_thread.cpp -o test_thread
In file included from test_thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:332:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:342:5: note: in instantiation of function template specialization
'std::__1::__thread_execute<void (Functor::*)(), std::__1::reference_wrapper<Functor> , 1>' requested here
__thread_execute(*__p, _Index());
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:354:42: note: in instantiation of function template specialization
'std::__1::__thread_proxy<std::__1::tuple<void (Functor::*)(), std::__1::reference_wrapper<Functor> > >' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
^
test_thread.cpp:19:15: note: in instantiation of function template specialization 'std::__1::thread::thread<void (Functor::*)(), std::__1::reference_wrapper<Functor> , void>'
requested here
std::thread thread (&Functor::execute, std::ref(functor));
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/type_traits:1001:5: note: '~__nat' has been explicitly marked deleted
here
~__nat() = delete;
^
1 error generated.
I can't figure out how to get around this, it seems like a compiler bug to me. For reference, the version of clang on that Mac is:
$ clang++ --version
Apple LLVM version 6.0 (clang-600.0.54) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin13.4.0
Thread model: posix
Any ideas what it is I'm doing wrong?
Thanks!
Donald.
The standard does not require the std::thread constructor - or the similar std::async for that matter - to unwrap a reference_wrapper when passed as the first argument with a pointer-to-member-function the way std::bind does. Pass a pointer to Functor instead of a reference_wrapper. (See Library Active Issues list DR2219.)

Existence of "simd reduction(:)" In GCC and MSVC?

simd pragma can be used with icc compiler to perform a reduction operator:
#pragma simd
#pragma simd reduction(+:acc)
#pragma ivdep
for(int i( 0 ); i < N; ++i )
{
acc += x[i];
}
Is there any equivalent solution in msvc or/and gcc?
Ref(p28): http://d3f8ykwhia686p.cloudfront.net/1live/intel/CompilerAutovectorizationGuide.pdf
For Visual Studio 2012:
With options /O1 /O2/GL, to report vectorization use /Qvec-report:(1/2)
int s = 0;
for ( int i = 0; i < 1000; ++i )
{
s += A[i]; // vectorizable
}
In the case of reductions over "float" or "double" types, vectorization requires that the /fp:fast switch is thrown. This is because vectorizing the reduction operation depends upon "floating point reassociation". Reassociation is only allowed when /fp:fast is thrown
Ref(associated doc;p12) http://blogs.msdn.com/b/nativeconcurrency/archive/2012/07/10/auto-vectorizer-in-visual-studio-11-cookbook.aspx
GCC definitely can vectorize. Suppose you have file reduc.c with contents:
int foo(int *x, int N)
{
int acc, i;
for( i = 0; i < N; ++i )
{
acc += x[i];
}
return acc;
}
Compile it (I used gcc 4.7.2) with command line:
$ gcc -O3 -S reduc.c -ftree-vectorize -msse2
Now you can see vectorized loop in assembler.
Also you may switch on verbose vectorizer output say with
$ gcc -O3 -S reduc.c -ftree-vectorize -msse2 -ftree-vectorizer-verbose=1
Now you will get console report:
Analyzing loop at reduc.c:5
Vectorizing loop at reduc.c:5
5: LOOP VECTORIZED.
reduc.c:1: note: vectorized 1 loops in function.
Look at the official docs to better understand cases where GCC can and cannot vectorize.
gcc requires -ffast-math to enable this optimization (as mentioned in the reference given above), regardless of use of #pragma omp simd reduction.
icc is becoming less reliant on pragma for this optimization (except that /fp:fast is needed in absence of pragma), but the extra ivdep and simd pragmas in the original post are undesirable. icc may do bad things when given a pragma simd which doesn't include all relevant reduction, firstprivate, and lastprivate clauses (and gcc may break with -ffast-math, particularly in combination with -march or -mavx).
msvc 2012/2013 are very limited in auto-vectorization. There are no simd reductions, no vectorization within OpenMP parallel regions, no vectorization of conditionals, and no advantage is taken of __restrict in vectorizations (there is some run-time check to vectorize less efficiently but safely without __restrict).

G++: linker doesnt seem to link correctly

I try to compile a program I have to control a DAQ device. In Windows, g++ compile and links OK, but in Linux it doesn't. The linker (called by G++) displays:
g++ -Wall -o "acelerar-30-0" "acelerar-30-0.cpp" (en el directorio: /home/poly/)
/tmp/ccRLpB4q.o: In function `main':
acelerar-30-0.cpp:(.text+0x429): undefined reference to `AdxInstantAoCtrlCreate'
collect2: ld returned 1 exit status
Ha fallado la compilaciĆ³n.
The cpp file is this (cut):
include stdlib.h
include stdio.h
include math.h
include "compatibility.h"
include "bdaqctrl.h"
include "comunes.h"
using namespace Automation::BDaq;
define deviceDescription L"USB-4704,BID#0"
int32 channelStart = 0;
int32 channelCount = 1;
double voltaje[0];
int32 modo;
int32 ms;
int main(int argc, char* argv[])
{
if (argc!=3)
salidaerror(argv[0],1);
channelStart = atoi(argv[1]);
ms = atoi(argv[2]);
if (channelStart<0||channelStart>1||ms<10)
salidaerror(argv[0],1);
ErrorCode ret = Success;
InstantAoCtrl * instantAoCtrl = AdxInstantAoCtrlCreate();
...
I have been several hours on this, and can't find the answer. The SDK is for Debian/Ubuntu, and it has the same code for Linux and Windows.
Any hints? Thanks
EDIT: Removed some marks as the formatting was incorrect
In my (limited) experience, typical gcc behavior will require that you specify the library containing that function as an argument on the command line like so:
-lsome_library
This is required even if the library is in your library path (additional library paths can be specified with -L). Find the appropriate library file containing that function and use its filename minus extensions and leading "lib" in the argument format above.

How to use make and compile as C99?

I'm trying to compile a linux kernel module using a Makefile:
obj-m += main.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Which gives me:
main.c:54: warning: ISO C90 forbids mixed declarations and code
I need to switch to C99. After reading I noticed I need to add a flag -std=c99, not sure where it suppose to be added.
How do I change the Makefile so it will compile as C99?
The correct way to add compiler flags when compiling modules is by setting the ccflags-y variable. Like this:
ccflags-y := -std=gnu99
See Documentation/kbuild/makefiles.txt in the kernel tree for more information.
Note that I'm using the gnu99 standard instead of c99 since the Linux kernel heavily relies on GNU extensions.
You could just add
CFLAGS=-std=c99
To the top of your makefile, or you can make the code compliant with C90 (as LukeN suggests.)
It's got nothing to do with the makefile. ISO C90 forbids declaring variables anywhere but in the beginning of a block or the file - like this
int main(int argc, char **argv) {
int a; /* Ok */
int b = 3; /* Ok */
printf("Hello, the magic number is %d!\n", b);
int c = 42; /* ERROR! Can only declare variables in the beginning of the block */
printf("I also like %d.. but not as much as %d!\n", c, b);
return 0;
}
Thus it has to be modified to this...
int main(int argc, char **argv) {
int a; /* Ok */
int b = 3; /* Ok */
int c = 42; /* Ok! */
printf("Hello, the magic number is %d!\n", b);
printf("I also like %d.. but not as much as %d!\n", c, b);
return 0;
}
You can only "fix" that in the source code, not in the makefile.
This rule has been relaxed in C99, but in my opinion it's a good idea to separate variable definitions, declarations and initializations from the code below it :)
So to change your makefile to make it compile with C99, you need to change the Makefile in the "build" directory that your makefile is referencing, and add the "-std=c99" at the "gcc" line compiling the source file.

Resources