Posts

Showing posts with the label c

A quick way to test whether all array elements are zero

4 TL;DR I would like to know how to clean up the first if statement. I tried looking online and found nothing. I am writing a program to test whether a number typed by the user has repeated digits. I have managed to create a 10-element boolean array (a[10]) such that if a[i] equals 0, this means that the digit 'i' is present in the typed number at most once. If a[i] equals 1, then the digit 'i' is present in the typed number at least twice (thus is repeated). Note 0<=i<=9. Now I am trying to analyse the values in this array such that if all values equal zero then we type "Repeated digit". And if not we say which numbers are repeated. if(a[0] == 0 && a[1] == 0 && a[2] == 0 && a[3] == 0 && a[4] == 0 &...

Why does a function that returns int not need a prototype?

6 I tried this program on DevC++ that would call two different types of function, one returning int and one returning char . I'm confused why the int function doesn't need a prototype, while the char one and any other type of function does. #include <stdio.h> //int function1(); char function2() ; int main (){ int X = function1() ; char Y = function2() ; printf("%d", X) ; printf ("%c", Y) ; return 0 ; } int function1(){ return 100 ; } char function2(){ return 'B' ; } The output: 100B If I remove the prototype for the char function, it results in: [Error] conflicting types for 'function2' [Note] previous implicit declaration of 'function2' was here ...

How to provide an implementation of memcpy

34 3 I am trying to write some bare metal code with a memset -style loop in it: for (int i = 0; i < N; ++i) { arr[i] = 0; } It is compiled with GCC and GCC is smart enough to turn that into a call to memset() . Unfortunately because it's bare metal I have no memset() (normally in libc) so I get a link error. undefined reference to `memset' It seems like the optimisation that does this transformation is -ftree-loop-distribute-patterns : Perform loop distribution of patterns that can be code generated with calls to a library. This flag is enabled by default at -O2 and higher, and by -fprofile-use and -fauto-profile . So one person's solution was to just lower the optimisation level. Not very satisfying. I also found this really helpful page th...

I need a way in a C preprocessor #if to test if a value will create a 0-size array

58 4 I have a structure that must pad out to 64K to fit perfectly in an embedded project, so that it fills out a flash block. So there is a #define that adds up the elements in the structure using sizeof() and determines how big the pad[] at the end needs to be to cause the total size to be 64K. For example, #define SIZE_OF_MY_PAD (0x10000 - (sizeof(uint16_t) + sizeof(uint8_t)*32 + ... )) typedef struct { uint16_t firstElement; uint8_t secondElementArray[32]; ... uint8_t pad[SIZE_OF_MY_PAD]; }; This has worked great for a long time until suddenly we don't need the pad at all in certain build configurations because it is already exactly 64k. This causes the code to fail because our compiler (not GCC) does not allow pad[0]. I have tried various ways to...

In C++, am I paying for what I am not eating?

Let's consider the following hello world examples in C and C++: main.c #include <stdio.h> int main() { printf("Hello world\n"); return 0; } main.cpp #include <iostream> int main() { std::cout<<"Hello world"<<std::endl; return 0; } When I compile them in godbolt to assembly, the size of the C code is only 9 lines (gcc -O3): .LC0: .string "Hello world" main: sub rsp, 8 mov edi, OFFSET FLAT:.LC0 call puts xor eax, eax add rsp, 8 ret But the size of the C++ code is 22 lines (g++ -O3): .LC0: .string "Hello world" main: sub rsp, 8 mov edx, 11 mov esi, OFFSET FLAT:.LC0 mov edi, OFFSET FLAT:_ZSt4cout call std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char...

Why do I get this particular color pattern when using rand()?

I tried to create a bmp file, like this: uint8_t raw_r[pixel_width][pixel_height]; uint8_t raw_g[pixel_width][pixel_height]; uint8_t raw_b[pixel_width][pixel_height]; uint8_t blue(uint32_t x, uint32_t y) { return (rand()%2)? (x+y)%rand() : ((x*y%1024)%rand())%2 ? (x-y)%rand() : rand(); } uint8_t green(uint32_t x, uint32_t y) { return (rand()%2)? (x-y)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand(); } uint8_t red(uint32_t x, uint32_t y) { return (rand()%2)? (y-x)%rand() : ((x*y%1024)%rand())%2 ? (x+y)%rand() : rand(); } for (y=0; y<pixel_height; ++y) { for (x=0; x<pixel_width; ++x) { raw_b[x][y]=blue(x, y); raw_g[x][y]=green(x, y); raw_r[x][y]=red(x, y); } } I expected to get something random (white noise). However, the output is interesting: Do you know the reason why? Now, it is clear that it has nothing to do with rand(). Also try this code: for (x=0; x<pixel_width; ++x) for (y=0; y<p...

Why does return 0 or break not work with the comma operator?

I can write the code if(1) x++, y++; instead of if(1) {x++; y++;}, but in some cases it does not work (see below). It would be nice if you tell me about this. int x = 5, y = 10; if (x == 5) x++, y++; // It works if (x == 5) x++, return 0; // It shows an error The same applies to for loops: for (int i = 0; i < 1; i++) y++, y += 5; // It works for (int i = 0; i < 1; i++) y++, break; // Does not work That's because return and break are statements, not expressions. As such, you cannot use it in another expression in any way. if and the others are similarly also statements. What you can do however is rewrite your expression (for return) so that it's not nested in an expression - not that I recommend writing code like that: return x++, 0; You can't do that for break because it doesn't accept an expression. The comma operator is for expressions. The return statement and other pure statements are not expressions. The comma operator is a binary operator ...

What's the meaning of “reserved for any use”?

NOTE: This is a c question, though I added c++ in case some C++ expert can provide a rationale or historical reason why C++ is using a different wording than C. In the C standard library specification, we have this normative text, C17 7.1.3 Reserved identifiers (emphasis mine): All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use. All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces. Now I keep reading answers on SO by various esteemed C experts, where they claim it is fine for a compiler or standard library to use identifiers with underscore + uppercase, or double underscore. Doesn't "reserved for any use" mean reserved for anyone except future extensions to the C language itself? Meaning that the implementation is not allowed to use them. While the second phrase above, regarding single leading ...

What happens if I write less than 12 bytes to a 12 byte buffer?

Understandably, going over a buffer errors out (or creates an overflow), but what happens if there are less than 12 bytes used in a 12 byte buffer? Is it possible or does the empty trailing always fill with 0s? Orthogonal question that may help: what is contained in a buffer when it is instantiated but not used by the application yet? I have looked at a few pet programs in Visual Studio and it seems that they are appended with 0s (or null characters) but I am not sure if this is a MS implementation that may vary across language/ compiler. Consider your buffer, filled with zeroes: [00][00][00][00][00][00][00][00][00][00][00][00] Now, let's write 10 bytes to it. Values incrementing from 1: [01][02][03][04][05][06][07][08][09][10][00][00] And now again, this time, 4 times 0xFF: [FF][FF][FF][FF][05][06][07][08][09][10][00][00] what happens if there are less than 12 bytes used in a 12 byte buffer? Is it possible or does the empty trailing always fill with 0s? You write as much as...