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.
Using Qt Creator I made these plain C files just to test my understanding:
main.c
#include <stdio.h>
#include "linked.h"
int main()
{
printf("Hello World!\n");
printf("%d", linked());
return 0;
}
linked.h
#ifndef LINKED_H_
#define LINKED_H_
int linked(void);
#endif // LINKED_H
linked.c
int linked()
{
return 5;
}
The IDE shows a warning on the line of linked.h in-between #define LINKED_H_ and int linked(void); which reads
ISO C requires a translation unit to contain at least one declaration
My best guess about what this means is that any header or other C file, if it is in a project, should get used in the main file at least once somewhere. I've tried searching the warning but if this has been answered elsewhere, I'm not able to understand the answer. It seems to me I've used the linked function and so it shouldn't give me this warning. Can anyone explain what's going on?
The program compiles and runs exactly as expected.
I think the issue is that you don't #include "linked.h" from linked.c. The current linked.c file doesn't have any declarations; it only has one function definition.
To fix this, add this line to linked.c:
#include "linked.h"
I don't know why it says this is an issue with linked.h, but it seems to be quite a coincidence that the line number you pointed out just happens to be the line number of the end of linked.c.
Of course, that may be all this is; a coincidence. So, if that doesn't work, try putting some sort of external declaration in this file. The easiest way to do that is to include a standard header, such as stdio.h. I would still advise you to #include "linked.h" from inside linked.c, though.
add a header
#ifndef LINKED_H_
#define LINKED_H_
#include <stdio.h>
int linked(void);
#endif // LINKED_H
The way you wrote the code, you need to use:
extern int linked(void);
(notice the additional "extern"). That might help with the issue.
Also, the code in linked.c should be:
int linked(void)
{
return 5;
}
(Notice the "parameter" - "void").
According to IBM, you need some declaration in the header file, but you do have one. Perhaps LINKED_H_ is defined elsewhere, or the compiler is seeing that it's possible that the precompiler condition might result in an empty parse.
Perhaps this header file will work for you:
linked.h
#ifndef LINKED_H_
#define LINKED_H_
int linked(void);
#endif // LINKED_H
char __allowLinkedHToBeIsoCCompliant = 1;
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'm trying to compile a simple C program using gcc:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lbryTest.h"
int main(int argc, char *argv[]) {
double x = 0.0;
x = lbryTest(2.0, 5.0);
printf("%f", x);
printf("Placeholder");
return 0;
}
lbryTest() is a function that does some simple math operations and returns a double. It is declared in lbryTest.h, and defined in liblbryTest.a.
When I compile the code using
gcc libraryTest.c -l lbryTest
I get the error:
cannot find -llbryTest.
How can I fix this?
Thanks to John Bollinger's comment, it finds the library. I added -L. to the command. This doesn't however answer why it was unable to find the library in the first place. The files are all in the same directory. How can I make it so the library will be found without explicitly adding the path? Or is that unconventional in C, and you should always explicitly add the path to all libraries linked?