I would like to report an intriguing bug I have. The piece of code below is supposed to print out 20 times "1.0". Instead, when compiling with icc (11.1) on my mac (snow leopard 10.6.8), I get unstable values (16 times "0.0" then 4 times "1.0"). I make use of several features in the code but none of them seems to have a bad syntax (no error during compilation, and valgrind reports no error during running). However if I change anything (even non used function - that's why I find it very strange), I get the correct output. Compiling with gcc gives the correct output as well.
But I think the strangest thing is that if I delete the function "function1", the bug disappears, although the function is NOT used in the code.
This is really odd, and now I fear that my code (which is much bigger than that) will be unstable. I need your help, I'm really puzzled by this. Is there anything wrong in the syntax?
main.c:
#include "main.h"
int main(argc,argv)
int argc;
char **argv;
{
Config para;
para.option1 = ONE;
para.a[0] = 0.0;
para.a[1] = 0.0;
para.a[2] = 0.0;
para.a[3] = 1.0;
int i;
double *x = (double *)malloc(20*sizeof(double));
for(i=0;i<20;i++) x[i] = 1.0;
for(i=0;i<20;i++) printf("%f \n", x[i]);
free(x);
function2(para);
return EXIT_SUCCESS;
}
void function1(int option){
switch(option){
case ONE: case TWO: case THREE: case MONE:
printf("MONE to THREE\n");
break;
case FOUR:
printf("FOUR\n");
break;
}
return;
}
void function2(const Config para){
if(para.option1 == FOUR){
printf("FOUR\n");
}
return;
}
main.h:
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <math.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
#define MONE -1
#define ONE 1
#define TWO 2
#define THREE 3
#define FOUR 4
typedef struct Config
{
int option1, option2;
double a[4];
} Config;
void function1(int option);
void function2(const Config para);
When digging more on the web, I found this bug report from Intel:
http://software.intel.com/en-us/articles/intel-compiler-and-xcode-322-linker-runtime-crash-with-switch-statement/
It seems to be related to how the icc compiler optimizes case statements. Their suggestions to solve the problem are the following:
1) Use Xcode 3.2.1 with 11.1 compiler.
2) Use 11.1 compiler with the option -use-asm with Xcode 3.2.2, 3.2.3, 3.2.4.
It should fix most cases but there are some cases when even generating object file through external assembler L* symbols still may appear in object file. Those cases are usually constant string literals placed in cstring section
3) Use Intel Composer XE.
My Xcode is version 3.2.6, but solution 2) solved my problem. I remain however quite puzzled about this (and the lack of documentation on the web).
Thanks.
Related
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 want to check if the user input is purely integer or a float. I attempted to do this by using floor and ceilfand comparing the values to the original x value in a function. However, this seems to be a tad bit problematic as the function keeps returning 0 instead of 1 for certain numbers like 5.5, when floor(5.5)!=5.5 and ceilf(5.5)!=5.5. This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdbool.h>
int intchecker(float x)//in a separate file
{
if (floor(x)==x && ceilf(x)==x)
{
//printf("%f",floor(x));
return 0;
}
else {
return 1;
}
}
int main()
{
char line[] = " +----+----+----+----+----+----+----+----+----+----+---+";
char numbers[] = " 0 5 10 15 20 25 30 35 40 45 50";
float balls,slots;
int slot[9];
printf("==========================================================\nGalton Box Simulation Machine\n==========================================================\n");
printf("Enter the number of balls [5-100]: ");
scanf("%f",& balls);
if (balls>100 || balls<5){
printf("/nInput is not within the range. Please try again.");
}
else if (intchecker(balls)==1){
printf("/nInput is not an integer. Please try again.");
}
else {
printf(" This is an integer.");
//some more code here
}
}
I tried placing just the intchecker code in another project, which seems to work fine without any bugs, unlike in the previous project, where when I used a printf statement to check if the floor(x) value was correct, it kept showing different answers, e.g. "-2.000000" when input was 5.2. This is my code for the second project:
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
int main()
{
float x;
scanf("%f",&x);
if (floor(x)==x && ceilf(x)==x){
printf("Integer");
return 0;
}
else {
printf("Non-Integer");
return 1;
}
}
How is it possible that the second code works perfectly when the first code does not? Is something wrong with my way of writing/calling the function?(I am relatively new to functions-only 2 weeks of exposure so far)
I searched online and have seen many answers to check if input is integer or float, even on stackoverflow.com itself, but my wish is not to find out other ways to check if input is integer or float (for if I wished to do that, I could just google it, and there are many such questions on stackoverflow.com as well), but to comprehend why my first code does not work, for, as far as I know, it ought to work well without any of the bugs it is currently facing.
Any help is greatly appreciated!:)
Assuming a missing function declaration:
main.c is missing the prototype for int intchecker(float x) so main.c assumes the old-school prototype of int intchecker(int x) and the code exhibits undefined behavior. Anything could happen.
Add prototype in main.c or put it in separate.h and include that header file here and in separate.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdbool.h>
int intchecker(float x);
int main(void) {
...
I'm writing a program for vocabulary training, for myself. And the program itself should be available in different languages, atm in German and English.
What I want is to have a main file which manage all and two separate files for the functions in the right language.
I compile all the files with:
gcc vocTrainer.c german_menue.c english_menue.c -o v.exe
But I get an error of multiple definition even though I only include one of the language files depending on your input.
Multiple defintion of 'orderOfVoc'
First defined here: collect2.exe error: ld returned 1 exit status
My code:
vocTrainer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "german_menue.h"
#include "english_menue.h"
int main(void)
{
char selectLang[1]; //store 1 for English or 2 for German
system("cls"); //clear screen
memset(selectLang,0,1); //set all fields in the array to 0
while(selectLang[1] != 1 && selectLang[1] != 2)
{
//select your language
printf("Choose language - Sprache auswaehlen:\n(1) - Englisch/English\n(2) - Deutsch/German\n");
scanf("%d",&selectLang[1]);
system("cls");
}
//language query
if(selectLang[1] == 2)
{
#include "german_menue.c"
}
else
{
#include "english_menue.c"
}
printf("Test of select Order: %d",orderOfVoc());
return 0;
}
german_menue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "german_menue.h"
int orderOfVoc()
{
char selectOrder[1]; /*store the choosen order of vocabulary.
1 for one after another 2 for a random sequence of words*/
printf("Wie sollen die Vokabeln abgefragt werden?\n(1) - Der Reihe nach\n(2) - Zufaellig\n");
scanf("%d",&selectOrder[1]);
return selectOrder[1];
}
english_menue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "german_menue.h"
int orderOfVoc()
{
char selectOrder[1]; /*store the choosen order of vocabulary.
1 for one after another 2 for a random sequence of words*/
printf("How do you want to learn the vocabulary?\n(1) - Vocabulary in order\n(2) - Random order\n");
scanf("%d",&selectOrder[1]);
return selectOrder[1];
}
german_menue.h
#ifndef GERMAN_MENUE_H //include guards
#define GERMAN_MENUE_H
extern int orderOfVoc();
#endif //GERMAN_MENUE_H
english_menue.h
#ifndef ENGLISH_MENUE_H //include guards
#define ENGLISH_MENUE_H
extern int orderOfVoc();
#endif //ENGLISH_MENUE_H
Primary Issue: In your code,
if(selectLang[1] == 2)
{
#include "german_menue.c"
}
else
{
#include "english_menue.c"
}
is not doing what you're thinking. There are may issues, like
#include is compile time operation (during preprocessing state) and essentially cannot be controlled at runtime.
You don't include source files. You compile and link them together. Your compilation statement looks correct. Just leave out the above mentioned code snippet from your code.
Just to add a bit detail regarding the reason behind the error you received, is because, you have #includeed the source files (which is essentially adding the source code of that .c file in vocTrainer.c file itself) and again, at compile time, you're putting the .c files. Thus, after compilation, at linking state, compiler sees more than one occurrences of orderOfVoc() which is why compiler is complaining.
Solution:
You remove different definition of orderOfVoc() function. Make use of the user selected value. Pass the value to the orderOfVoc() as an argument, and execute accordingly.
Secondary Issue(s): Apart from above issue(s), in your code, with a definition like
char selectLang[1];
writing
scanf("%d",&selectLang[1]);
is wrong, because
selectLang[1] is out of bound access. Array index in C starts from 0.
%d is not the correct formart specifier for char.
FWIW, char selectLang[1]; is functionally equivalent with char selectLang;
A modified version (not tested) for aforesaid approach:
select_menue.h
#ifndef SELECT_MENUE_H //include guards
#define SELECT_MENUE_H
//according to {store 1 for English or 2 for German}
#define ENGLISH 1
#define GERMAN 2
extern int orderOfVoc(int);
#endif //SELECT_MENUE_H
select_menue.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "select_menue.h"
int orderOfVoc(int lang)
{
int selectOrder = 0;
switch (lang)
{
case ENGLISH:
printf("How do you want to learn the vocabulary?\n(1) - Vocabulary in order\n(2) - Random order\n");
scanf("%d",&selectOrder); //add possible error check
break;
case GERMAN:
printf("Wie sollen die Vokabeln abgefragt werden?\n(1) - Der Reihe nach\n(2) - Zufaellig\n");
scanf("%d",&selectOrder); //add possible error check
break;
}
return selectOrder;
}
vocTrainer.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "select_menu.h"
int main(void)
{
int selectLang = 0; //array not required, initialize in single statement
//store 1 for English or 2 for German
while(selectLang != 1 && selectLang != 2)
{
//select your language
printf("Choose language - Sprache auswaehlen:\n(1) - Englisch/English\n(2) - Deutsch/German\n");
scanf("%d",&selectLang);
}
printf("Test of select Order: %d",orderOfVoc(selectLang));
return 0;
}
#include is a preprocessor directive that includes the contents of the file named at compile time.
The code that conditionally includes stuff is executed at run time...not compile time. So both files are being compiled in. ( You're also including each file twice, once in the main function and once above it, which is just confusing and probably wrong, but we'll ignore that for now. )
You can't really conditionally include stuff at run time. You can use other preprocessor directives (#ifdef, etc. ) to conditionally include one or the other file at compile time, but for your purposes you really need to have some sort of global flag that each function in the included files uses to determine if it should display english or german, etc.
Internationalization of strings is a whole topic in itself. There are lots of ways to handle it, and some libraries to make it easier depending on your platform.
Here's one way you could handle the same scenari:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "german_menue.h"
char *getLocalizedString(int stringId)
{
// Pseudo-Code, not real C++
// Also ignores memory issues and deallocating strings when done
char *localizedString = LoadGermanOrEnglishStringBasedOnGlobalVarForLanguage(stringId);
return localizedString ;
}
int orderOfVoc()
{
int stringId = 1;//should be constant for this message
char *localizedString = getLocalizedString(stringId);
printf("%s", localizedString);
scanf("%d",&selectOrder[1]);
return selectOrder[1];
}
I encounter a strange error when compiling this
#include <termios.h>
#include <stddef.h>
struct Test {
int a;
int b;
};
void test() {
static int test_array[(offsetof(struct Test,a)) > 0 ? 2 : 1];
}
with arm-linux-androideabi-gcc -c:
test.c:8:13: error: storage size of 'test_array' isn't constant
The strange thing about this is, when I remove the
#include <termios.h>
the whole thing compiles without error. Also, when I use the gcc installed on my ubuntu system, it does not complain independent of including termios.h.
Ayone any Idea why?
Background: I am trying to compile a ghc (glasgow haskell compiler) android crosscompiler, and hs2hsc fails on this situation.
I have some code that looks similar to the following:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdarg.h>
#include <sys/ldr.h>
int main (int argc, char **argv)
{
int liRC = 0;
struct shl_descriptor *lstModDesc;
int liEach;
char lsBaseName[513];
char *lsTheName;
for( liEach = 0; liRC == 0; liEach++ )
{
liRC = shl_get( liEach, &lstModDesc );
if( liRC == 0 )
{
strcpy( lsBaseName, lstModDesc->filename );
lsTheName = (char *)basename( lsBaseName );
/* do more stuff */
}
}
return 0;
}
What it is doing is enumerating all the shared libraries attached to the binary. This compiles fine on AIX 5.3 but on AIX 7.1 I am getting the following concerning lstModDesc:
"modulename.c", line 2553.30: 1506-285
(S) The indirection operator cannot be
a pplied to a pointer to an incomplete
struct or union.
I cannot find where shl_get is defined on my aix 5.3 box nor can I find where struct shl_descriptor is defined either. I am stumped. I even tried outputing the preprocessed output with the -E flag to the compiler with no luck. I did a recursive grep in /usr/include. Is there somewhere else I should be searching? Where are those definitions?
Are you sure that bit of the code was included in the compilation on AIX 5.3? I just went Google-whacking with 'site:ibm.com shl_descriptor' and there is precisely one item found:
http://www-01.ibm.com/support/docview.wss?uid=swg21212239
It is pointing to a problem on HP-UX with WAS (WebSphere Application Server). There is sample code which uses <dl.h> (dynamic loader), and shows shl_descriptor and shl_gethandle() and shl_load().
Given the complete absence of hits for anything in AIX and the presence of the HP-UX platform, then you have a slightly different problem to resolve. The question is:
Why is the conditional compilation on AIX 5.3 excluding the section that uses shl_descriptor and not excluding it on AIX 7.1. You should look at the conditions wrapped around that code in the #ifdef line, and see what is used to trigger the HP-only compilation on AIX 5.3.