I am using MSYS2 mingw 64 when compiling code that needs the header random.h I am trying to make that code work on both Linux and windows with the least amount of changes
#include <sys/random.h>
#include <time.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
srand(time(NULL));
return 0;
}
I ran this command pacman -S msys2-runtime-devel to download the random.h header file and it is located in sys official link
on linux, the file is included using #include <linux/random.c> but I don't know what to use on windows or if I have to do something completely different
When I comment the first line I get this warning
main.c:10:9: warning: implicit declaration of function 'srand' [-Wimplicit-function-declaration]
10 | srand(time(NULL));
| ^~~~~
As per the linked documentation,
srand is declared in #include <stdlib.h>.
rand is declared in #include <stdlib.h>.
Neither requires including random.h or linux/random.c.
I'm new to C and programming.
I'm on Windows 10, I just installed Dev-C++ and I'm learning how to call functions from other files: i wrote this function to sum two numbers, and I call it from the main script.
The problem is that when i compile the func.c file I get the error in title, so if I run the main file it doesn't recognize the "sum" function.
This is the main.c file:
#include <stdio.h>
#include "func.h"
main(){
int x,y,s;
scanf("%d %d",&x,&y);
s = sum(x,y);
printf("\n%d",s);
}
This is the header file:
#ifndef FUNC_H_INCLUDED
#define FUNC_H_INCLUDED
int func(int a, int b);
#endif // FUNC_H_INCLUDED
And this is the code of the sum function in a func.c file:
#include <stdio.h>
#include "func.h"
int func(int a, int b){
return(a+b);
}
I did read lots of other questions, but they didnt help in my case, or I didnt get the tricky answer.
Thank you.
In case you are using Embarcadero's Dev-C++. I use their free compiler since it is "portable".
func.c and func.h both contain a function called func while your main file has a function called sum, you must have a consistency in the names, you can do s=func(x,y) and that should work, but a good practice is doing the opposite and replace func in other files by sum.
And you must compile the 3 files, compiling 1 or 2 isn't enough.
To compile them using Embarcadero's free compiler:
C:\path\to\compiler\bcc32x func.c func.h main.c
It will give you main.exe that you can run from the command prompt.
Apologies for the dumb question. I checked all similar questions for the same error on stackoverflow, but it didn't help me understand why this error is happening in the following code.
I have one additional header file and a source file, which is included in the main file, and when I compile, I am getting the following error. I am trying to pass the char** argv from the main() to another function defined in another header file.
#include "include/Process.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv) {
if (argc < 2) {
printf("Please provide a path to file\n");
return (EXIT_FAILURE);
}
Process(argv);
Process.h:
#pragma once
extern void Process(char** path);
Process.c:
#include <stdio.h>
#include "../include/Process.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <syslog.h>
#include <sys/types.h>
#include <unistd.h>
void Process(char** path) {
printf("%s\n", path[1]);
}
It gets compiled but the warning is
./src/Process.c:22:6: error: conflicting types for ‘Process’
void Process(char** path) {
^
./include/Process.h:17:6: note: previous declaration of ‘Process’ was here
extern void Process(char** path);
^
However, the warning disappears when I change the type of path from char** to char* and pass argv[1] instead of argv.
I am clueless why this is happening like this, and according to
this similar post, I tried adding a forward declaration for char** path above extern void Process(char** path); in the Process.h file, but it didn't help either.
Why is this error thrown when using char** path?
Why it disappears when I use char* path?
So far, I am able to see the program running, even with this warning. Is it safe to ignore this warning? If not, what could be the possible effects it can have during runtime?
Using gcc version 4.9.2 (Ubuntu 4.9.2-10ubuntu13)
Thanks.
Try putting your custom includes after the system includes.
It might be possible that the custom include defines a macro which interferes with the system includes. To minimize the risk of this, I always put the Standard C includes first, then any OS includes, and then third party libraries, and then my own ones
In theory the custom include shouldn't do this, and the system includes should only use reserved names, but in practice this doesn't always happen.
As clang-format is a tool to only reformat code, is it possible that such formatting can break working code or at least change how it works? Is there some kind of contract that it will/can not change how code works?
We have a lot of code that we want to format with clang-format. This means, many lines of code will change. Not having to review every single line of code that only changed due to a clang-format would be a big simplification of this process.
I would say that clang-format will not change how code works. On the other hand I am not 100% sure, if this can be guaranteed.
Short answer: YES.
The clang-format tool has a -sort-includes option. Changing the order of #include directives can definitely change the behavior of existing code, and may break existing code.
Since the corresponding SortIncludes option is set to true by several of the built-in styles, it might not be obvious that clang-format is going to reorder your includes.
MyStruct.h:
struct MyStruct {
uint8_t value;
};
original.c:
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
Now let's say we run clang-format -style=llvm original.c > restyled.c.
restyled.c:
#include "MyStruct.h"
#include <stddef.h>
#include <stdint.h>
int main(int argc, char **argv) {
struct MyStruct s = {0};
return s.value;
}
Due to the reordering of the header files, I get the following error when compiling restyled.c:
In file included from restyled.c:1:
./MyStruct.h:2:5: error: unknown type name 'uint8_t'
uint8_t value;
^
1 error generated.
However, this issue should be easy to work around. It's unlikely that you have order-dependent includes like this, but if you do, you can fix the problem by putting a blank line between groups of headers that require a specific order, since apparently clang-format only sorts groups of #include directives with no non-#include lines in between.
fixed-original.c:
#include <stdint.h>
#include <stddef.h>
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
fixed-restyled.c:
#include <stddef.h>
#include <stdint.h>
#include "MyStruct.h"
int main(int argc, char **argv) {
struct MyStruct s = {0};
return s.value;
}
Note that stdint.h and stddef.h were still reordered since their includes are still "grouped", but that the new blank line prevented MyStruct.h from being moved before the standard library includes.
However...
If reordering your #include directives breaks your code, you should probably do one of the following anyway:
Explicitly include the dependencies for each header in the header file. In my example, I'd need to include stdint.h in MyStruct.h.
Add a comment line between the include groups that explicitly states the ordering dependency. Remember that any non-#include line should break up a group, so comment lines work as well. The comment line in the following code also prevents clang-format from including MyStruct.h before the standard library headers.
alternate-original.c:
#include <stdint.h>
#include <stddef.h>
// must come after stdint.h
#include "MyStruct.h"
int main (int argc, char **argv) {
struct MyStruct s = { 0 };
return s.value;
}
For sure it can change how your code works. And the reason is C program can view some properties of its source code. What I'm thinking about is __LINE__ macro, but I'm not sure there are no other ways.
Consider 1.c:
#include <stdio.h>
int main(){printf("%d\n", __LINE__);}
Then:
> clang 1.c -o 1.exe & 1.exe
2
Now do some clang-format:
> clang-format -style=Chromium 1.c >2.c
And 2.c is:
#include <stdio.h>
int main() {
printf("%d\n", __LINE__);
}
And, of course, output has changed:
> clang 2.c -o 2.exe & 2.exe
3
Since clang-format affects only whitespace characters, you can check that files before and after clang-formating are identical up to whitespaces. In Linux/BSD/OS X you can use diff and tr for that:
$ diff --ignore-all-space <(tr '\n' ' ' < 2.c ) <(tr '\n' ' ' < 1.c)
1.c:
#include <stdio.h>
int main() {printf("Hello, world!\n"); return 0;}
2.c:
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
Output of diff command is empty, meaning that files 1.c and 2.c are identical up to whitespaces.
As Karoly mentioned in his comment, note that in ideal conditions you still have to check spaces that matters, e.g. string literals. But in the real world I believe this test is more than enough.
clang-format reformatted ASM code in a project because we effectively did this:
#define ASM _asm
ASM {
...
}
yes
it will not break the working flow
the system has the config switch:
"C_Cpp.clang_format_sortIncludes": false,
but it not work, i don't know what is wrong...
my version is:ms-vscode.cpptools-0.13.1
this is my solution:
for the stable working flow ,use the grammar:
// clang-format off
...here is your code
// clang-format on
It can break your code, if you use special constructs in your code and your settings for formatting.
Inline Assembler
If you normally compile your code with gcc and make use of gcc-style inline assembler, clang-format will very likely break the naming of register variables, as it sees the %-character as an operator.
asm_movq(%[val2], %%mm0)
will be reformatted as
asm_movq(% [val2], % % mm0)
which will no longer compile.
Constructing a Path in a macro
If you build up a path using macros without using strings, clang-format again will see the '/' character as an operator and will put spaces around it.
Boost e.g. uses a construct like this:
# define AUX778076_PREPROCESSED_HEADER \
BOOST_MPL_CFG_COMPILER_DIR/BOOST_MPL_PREPROCESSED_HEADER
to construct a path to a header file. The '/' is not an operator here, but as it is not inside a string, clang-format treats it as an operator and puts spaces around it, creating a different path.
The include of the header file will obviously fail.
Conclusion
Yes, clang-format can break your code. If you are using very specific constructs that are edge cases or outside of the language standard or simply extensions of your very specific compiler (which is not clang), then you will need to check the changes made by clang-format. Otherwise you risk getting hidden errors.
I imagine it would not, given that it is built on clang's static analysis, and therefore has knowledge of the structure of code itself, rather than just a dumb source code formatter that operates on the text alone(one of the boons of being able to use a compiler library). Given that the formatter uses the same parser and lexer as the compiler itself, I'd feel safe enough that it wouldn't have any issue spitting out code that behaves the same as what you feed it.
You can see the source code for the C++ formatter here: http://clang.llvm.org/doxygen/Format_8cpp_source.html
I have this simple code
#include <stdio.h>
#include <OpenGL/glext.h>
#include <OpenGL/gl.h>
int main (int argc, const char * argv[])
{
printf("Hello, World!\n");
return 0;
}
If I comment out the line with "glext.h" it compiles and runs fine in xcode 4 if I uncomment that line I get 345 errors most of them 'expected * before *' ...
What is going on?! both gl.h and glext.h are inside the OpenGL framework but no matter if I incluhe it or not I get the same error. I tried GCC 4.2 as well as LLVM GCC 4.2 and LLVM (in this case 21 semantic and parse errors).
I am sure my lack of experience with C is causing this but I am surprised gl.h has no problem but glext.h has.
Even if I try to compile in from the command line by gcc I get lots of
/System/Library/Frameworks/OpenGL.framework/Headers/glext.h:3137: error: expected ‘)’ before ‘const’
Any ideas?
It's a bug with glext.h. If you look at that file, you'll see that it has a bunch of definitions that use GLenum, but GLenum isn't defined anywhere in that file. So, before you include glext.h, you need to include a file that defines GLenum. The easiest thing to do is to include gl.h first instead of second:
#include <stdio.h>
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
Switch these two lines around:
#include <OpenGL/glext.h>
#include <OpenGL/gl.h>
And it should work.