I am trying to byte-align a function to 16-byte boundary using the 'aligned(16)' attribute. I did the following: void __attribute__((aligned(16))) function() { }
(Source: http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html)
But when I compile (gcc foo.c ; no makefiles or linker scripts used), I get the following error:
FOO.c:99: error: alignment may not be specified for 'function'
I tried aligning to 4,8,32, etc as well but the error remains the same.
I need this to align an Interrupt Service Routine for a powerpc-based processor. What is the correct way of doing so ?
Why don't you just pass the -falign-functions=16 to gcc when compiling?
Adapting from my answer on this GCC question, you might try using #pragma directives, like so:
#pragma GCC push_options
#pragma GCC optimize ("align-functions=16")
//add 5 to each element of the int array.
void add5(int a[20]) {
int i = 19;
for(; i > 0; i--) {
a[i] += 5;
}
}
#pragma GCC pop_options
The #pragma push_options and pop_options macros are used to control the scope of the optimize pragma's effect. More details about these macros can be found in the GCC docs.
Alternately, if you prefer GCC's attribute syntax, you should be able to do something like:
//add 5 to each element of the int array.
__attribute__((optimize("align-functions=16")))
void add5(int a[20]) {
int i = 19;
for(; i > 0; i--) {
a[i] += 5;
}
}
You are probably using an older version of gcc that does not support that attribute. The documentation link you provided is for the "current development" of gcc. Looking through the various releases, the attribute only appears in the documentation for gcc 4.3 and beyond.
Related
How can I tell GCC to unroll a particular loop?
I have used the CUDA SDK where loops can be unrolled manually using #pragma unroll. Is there a similar feature for gcc? I googled a bit but could not find anything.
GCC gives you a few different ways of handling this:
Use #pragma directives, like #pragma GCC optimize ("string"...), as seen in the GCC docs. Note that the pragma makes the optimizations global for the remaining functions. If you used #pragma push_options and pop_options macros cleverly, you could probably define this around just one function like so:
#pragma GCC push_options
#pragma GCC optimize ("unroll-loops")
//add 5 to each element of the int array.
void add5(int a[20]) {
int i = 19;
for(; i > 0; i--) {
a[i] += 5;
}
}
#pragma GCC pop_options
Annotate individual functions with GCC's attribute syntax: check the GCC function attribute docs for a more detailed dissertation on the subject. An example:
//add 5 to each element of the int array.
__attribute__((optimize("unroll-loops")))
void add5(int a[20]) {
int i = 19;
for(; i > 0; i--) {
a[i] += 5;
}
}
Note: I'm not sure how good GCC is at unrolling reverse-iterated loops (I did it to get Markdown to play nice with my code). The examples should compile fine, though.
GCC 8 has gained a new pragma that allows you to control how loop unrolling is done:
#pragma GCC unroll n
Quoting from the manual:
You can use this pragma to control how many times a loop should be
unrolled. It must be placed immediately before a for, while or do loop
or a #pragma GCC ivdep, and applies only to the loop that follows. n
is an integer constant expression specifying the unrolling factor. The
values of 0 and 1 block any unrolling of the loop.
-funroll-loops might be helpful (though it turns on loop-unrolling globally, not per-loop). I'm not sure whether there's a #pragma to do the same...
I've recently started to play around with OpenMP and like it very much.
I am a just-for-fun Classic-VB programmer and like coding functions for my VB programs in C. As such, I use Windows 7 x64 and GCC 4.7.2.
I usually set up all my C functions in one large C file and then compile a DLL out of it. Now I would like to use OpenMP in my DLL.
First of all, I set up a simple example and compiled an exe file from it:
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n = 520000;
int i;
int a[n];
int NumThreads;
omp_set_num_threads(4);
#pragma omp parallel for
for (i = 0; i < n; i++)
{
a[i] = 2 * i;
NumThreads = omp_get_num_threads();
}
printf("Value = %d.\n", a[77]);
printf("Number of threads = %d.", NumThreads);
return(0);
}
I compile that using gcc -fopenmp !MyC.c -o !MyC.exe and it works like a charm.
However, when I try to use OpenMP in my DLL, it fails. For example, I set up this function:
__declspec(dllexport) int __stdcall TestAdd3i(struct SAFEARRAY **InArr1, struct SAFEARRAY **InArr2, struct SAFEARRAY **OutArr) //OpenMP Test
{
int LengthArr;
int i;
int *InArrElements1;
int *InArrElements2;
int *OutArrElements;
LengthArr = (*InArr1)->rgsabound[0].cElements;
InArrElements1 = (int*) (**InArr1).pvData;
InArrElements2 = (int*) (**InArr2).pvData;
OutArrElements = (int*) (**OutArr).pvData;
omp_set_num_threads(4);
#pragma omp parallel for private(i)
for (i = 0; i < LengthArr; i++)
{
OutArrElements[i] = InArrElements1[i] + InArrElements2[i];
}
return(omp_get_num_threads());
}
The structs are defined, of course. I compile that using
gcc -fopenmp -c -DBUILD_DLL dll.c -o dll.o
gcc -fopenmp -shared -o mydll.dll dll.o -lgomp -Wl,--add-stdcall-alias
The compiler and linker do not complain (not even warnings come up) and the dll file is actually being built. But as I try to call the function from within VB, the VB compiler claims the the DLL file could not be found (run-time error 53). The strange thing about that is that as soon as one single OpenMP "command" is present inside the .c file, the VB compiler claims a missing DLL even if I call a function that does not even contain a single line of OpenMP code. When I comment all OpenMP stuff out, the function works as expected, but doesn't use OpenMP for parallelization, of course.
What is wrong here? Any help appreciated, thanks in advance! :-)
The problem most probably in this case is LD_LIBRARY_PATH is not set . You must use set LD_LIBRARY_PATH to the path that contains the dll or the system will not be able to find it and hence complains about the same
I got the following error message while compiling the C code:
error: 'for' loop initial declarations are only allowed in C99 mode
note: use option -std=c99 or -std=gnu99 to compile your code
What does it mean?
How to fix it?
You have done this:
for (int i=0;i<10;i++) {
And you need to change it to this:
int i;
for (i=0;i<10;i++) {
Or, as the error says,
use option -std=c99 or -std=gnu99 to compile your code.
Update copied from Ryan Fox's answer:
gcc -std=c99 foo.c -o foo
Or, if you're using a standard makefile, add it to the CFLAGS variable.
You'll still need C99 if you want to mix statements and variable declarations. As other answers and the error message itself say, add -std=c99 to the command-line when you compile to enable C99 features [1].
But you have always been allowed to write a compound statement (a "block", IOW, but the standard never uses this word!) in place of a single statement.
#include<stdio.h>
int main() {
int i = 5;
{ /* new block, new declarations. */
int i;
for (i=0;i<10;i++){
}
}
printf("%d\n", i); /* prints "5\n" */
}
This is legal in K&R, C90 (aka C89, it's the same thing), and C99.
Enabling C99 mode gets you lots of cool stuff, but it also disables some other cool stuff that gcc allows by default, like anonymous structures and unions within structures and unions.
-std=gnu99 probably enables "all the goodies", but I caution you to avoid doing this. It will make unnecessary difficulty if you (or others) wish to port the code. I'd probably have a windows version of my pet project, ported for free by somebody, had I not done this very thing. It ties you gcc. You don't want to be tied. That's the whole bloody point of standards.
The other answers give you a work around to deal with GCC's default mode. If you'd like to use C99, (which I do recommend in general) then you have to add that compiler flag:
gcc -std=c99 foo.c -o foo
Or, if you're using a standard makefile, add it to the CFLAGS variable.
It means you can't declare variables in for statement.
You should do:
int i ;
for( i = 0 ; i < len ; i++ )
What you are probably doing
for( int i = 0 ; i < len ; i++ )
How can I tell GCC to unroll a particular loop?
I have used the CUDA SDK where loops can be unrolled manually using #pragma unroll. Is there a similar feature for gcc? I googled a bit but could not find anything.
GCC gives you a few different ways of handling this:
Use #pragma directives, like #pragma GCC optimize ("string"...), as seen in the GCC docs. Note that the pragma makes the optimizations global for the remaining functions. If you used #pragma push_options and pop_options macros cleverly, you could probably define this around just one function like so:
#pragma GCC push_options
#pragma GCC optimize ("unroll-loops")
//add 5 to each element of the int array.
void add5(int a[20]) {
int i = 19;
for(; i > 0; i--) {
a[i] += 5;
}
}
#pragma GCC pop_options
Annotate individual functions with GCC's attribute syntax: check the GCC function attribute docs for a more detailed dissertation on the subject. An example:
//add 5 to each element of the int array.
__attribute__((optimize("unroll-loops")))
void add5(int a[20]) {
int i = 19;
for(; i > 0; i--) {
a[i] += 5;
}
}
Note: I'm not sure how good GCC is at unrolling reverse-iterated loops (I did it to get Markdown to play nice with my code). The examples should compile fine, though.
GCC 8 has gained a new pragma that allows you to control how loop unrolling is done:
#pragma GCC unroll n
Quoting from the manual:
You can use this pragma to control how many times a loop should be
unrolled. It must be placed immediately before a for, while or do loop
or a #pragma GCC ivdep, and applies only to the loop that follows. n
is an integer constant expression specifying the unrolling factor. The
values of 0 and 1 block any unrolling of the loop.
-funroll-loops might be helpful (though it turns on loop-unrolling globally, not per-loop). I'm not sure whether there's a #pragma to do the same...
I'm trying to solve the 3n+1 problem and I have a for loop that looks like this:
for(int i = low; i <= high; ++i)
{
res = runalg(i);
if (res > highestres)
{
highestres = res;
}
}
Unfortunately I'm getting this error when I try to compile with GCC:
3np1.c:15: error: 'for' loop initial
declaration used outside C99 mode
I don't know what C99 mode is. Any ideas?
I'd try to declare i outside of the loop!
Good luck on solving 3n+1 :-)
Here's an example:
#include <stdio.h>
int main() {
int i;
/* for loop execution */
for (i = 10; i < 20; i++) {
printf("i: %d\n", i);
}
return 0;
}
Read more on for loops in C here.
There is a compiler switch which enables C99 mode, which amongst other things allows declaration of a variable inside the for loop. To turn it on use the compiler switch -std=c99
Or as #OysterD says, declare the variable outside the loop.
To switch to C99 mode in CodeBlocks, follow the next steps:
Click Project/Build options, then in tab Compiler Settings choose subtab Other options, and place -std=c99 in the text area, and click Ok.
This will turn C99 mode on for your Compiler.
I hope this will help someone!
I've gotten this error too.
for (int i=0;i<10;i++) { ..
is not valid in the C89/C90 standard. As OysterD says, you need to do:
int i;
for (i=0;i<10;i++) { ..
Your original code is allowed in C99 and later standards of the C language.
#Blorgbeard:
New Features in C99
inline functions
variable declaration no longer restricted to file scope or the start of a compound statement
several new data types, including long long int, optional extended integer types, an explicit boolean data type, and a complex type to represent complex numbers
variable-length arrays
support for one-line comments beginning with //, as in BCPL or C++
new library functions, such as snprintf
new header files, such as stdbool.h and inttypes.h
type-generic math functions (tgmath.h)
improved support for IEEE floating point
designated initializers
compound literals
support for variadic macros (macros of variable arity)
restrict qualification to allow more aggressive code optimization
http://en.wikipedia.org/wiki/C99
A Tour of C99
if you compile in C change
for (int i=0;i<10;i++) { ..
to
int i;
for (i=0;i<10;i++) { ..
You can also compile with the C99 switch set. Put -std=c99 in the compilation line:
gcc -std=c99 foo.c -o foo
REF: http://cplusplus.syntaxerrors.info/index.php?title='for'_loop_initial_declaration_used_outside_C99_mode
For anyone attempting to compile code from an external source that uses an automated build utility such as Make, to avoid having to track down the explicit gcc compilation calls you can set an environment variable. Enter on command prompt or put in .bashrc (or .bash_profile on Mac):
export CFLAGS="-std=c99"
Note that a similar solution applies if you run into a similar scenario with C++ compilation that requires C++ 11, you can use:
export CXXFLAGS="-std=c++11"
Jihene Stambouli answered OP question most directly...
Question was;
why does
for(int i = low; i <= high; ++i)
{
res = runalg(i);
if (res > highestres)
{
highestres = res;
}
}
produce the error;
3np1.c:15: error: 'for' loop initial declaration used outside C99 mode
for which the answer is
for(int i = low...
should be
int i;
for (i=low...
Enable C99 mode in Code::Blocks 16.01
Go to Settings-> Compiler...
In Compiler Flags section of Compiler settings tab, select checkbox 'Have gcc follow the 1999 ISO C language standard [-std=c99]'
I had the same problem and it works you just have to declare the i outside of the loop:
int i;
for(i = low; i <= high; ++i)
{
res = runalg(i);
if (res > highestres)
{
highestres = res;
}
}
For Qt-creator: just add next lines to *.pro file...
QMAKE_CFLAGS_DEBUG = \
-std=gnu99
QMAKE_CFLAGS_RELEASE = \
-std=gnu99