Sequences in C in a time efficient manner - c

I am making a simulation that updates at every timestep. I nearly 'kill' the virtual organisms in my grid (its a cellular automatum) at 20000 timesteps. I want to write off data at killing_time - 10000 and killing_time - 100 for every 200 times I kill. Now I can write a for loop and iterate from 1 to 200 like this
for(i=1; i<=200; i++)
{
if(Time%(i*killing_time-10000)==0 || Time%(i*killing_time-100)==0)
{
etcetera. But than I would have to loop from 1 to 200 every timestep and do this calculation. How do I do this in an intelligent manner? Bram

As far as I understand your problem, this could be something like this...
/**
gcc -std=c99 -o prog_c prog_c.c \
-pedantic -Wall -Wextra -Wconversion \
-Wc++-compat -Wwrite-strings -Wold-style-definition -Wvla \
-g -O0 -UNDEBUG -fsanitize=address,undefined
**/
#include <stdio.h>
void
simulate(void)
{
const int killing_period=20000;
int killing_time=killing_period;
int Time=1;
for(int kill_event=1; kill_event<=200; ++kill_event)
{
for(; Time<killing_time; ++Time)
{
if(Time==(killing_time-10000) || Time==(killing_time-100))
{
printf("display at %d\n", Time);
}
// recompute the grid here
}
printf("kill at %d\n", Time);
killing_time+=killing_period;
}
printf("DONE\n");
}
int
main(void)
{
simulate();
return 0;
}

Related

Attribute for ignoring "too many arguments in call to 'func'"

I am creating a light test framework. For my local debugging in linux with gcc and clang, I do not get any complaints for mocking a function that has arguments, but mocking it with no arguments. eg.
add.c
int add(int a, int b) {
return a + b;
}
foo.c
#include "add.h"
int add_2(int a) {
return add(a, 2);
}
Now, in order to mock add. I simply created these macros.
testframework.h
#define DECLARE_MOCK(type, name) \
type __var_##name[255]; \
size_t __var_##name##_inc = 0; \
size_t __var_##name##_actual = 0; \
type name() { return (type)__var_##name[__var_##name##_inc++]; }
#define MOCK(name, value) __var_##name[__var_##name##_actual++] = value;
This works well on my linux machine. add(x,y) requires two arguments, but gcc or clang doesn't complain that the mock will essentially have no arguments passed to it, and works perfectly as a stand in. it's this line here type name() ...
Here is the usage. Notice I am mocking add.c capability in this test file.
#include "foo.h"
#include "testframework.h"
DECLARE_MOCK(int, add);
int main() {
DESCRIBE("things");
MOCK(add, 2);
SHOULDB("add", {
ASSERT(add(0, 2) == 2);
});
}
The issue comes in on gcc mac, which complains.
[INFO] CMD: gcc -Wall -Werror -std=c11 -O3 -o target/things tests/things.c obj/things/lib.o
tests/things.c:29:57: error: too many arguments in call to 'add' [-Werror]
SHOULDB("add", { ASSERT(add(0, 2) == 2); });
I would like to keep -Wall and -Werror, I was hoping there was an attribute I could add to the macro, which is the opposite of sentinel.

how to stub fgets in C while using Google Unit Test

I have currently been assigned to do unit tests on some problems that I've done during an introductory bootcamp, and I'm having problems understanding the concept of 'stub' or 'mock'.
I'm using Google Unit Test, and the problems from the bootcamp are solved in C.
int validate_input(uint32_t * input_value) {
char input_buffer[1024] = {0};
char * endptr = NULL;
int was_read_correctly = 1;
printf("Give the value for which to print the bits: ");
/*
* Presuming wrong input from user, it does not signal:
* - number that exceeds the range of uint_32 (remains to be fixed)
* For example: 4294967295 is the max value of uint_32 ( and this can be also confirmed by the output )
* If bigger numbers are entered the actual value seems to reset ( go back to 0 and upwards.)
*/
if (NULL == fgets(input_buffer, 1024, stdin)) {
was_read_correctly = 0;
} else {
if ('-' == input_buffer[0]) {
fprintf(stderr, "Negative number not allowed.\n");
was_read_correctly = 0;
}
}
errno = 0;
if (1 == was_read_correctly) {
* input_value = strtol(input_buffer, & endptr, 10);
if (ERANGE == errno) {
fprintf(stderr, "Sorry, this number is too small or too large.\n");
was_read_correctly = 0;
} else if (endptr == input_buffer) {
fprintf(stderr, "Incorrect input.\n(Entered characters or characters and digits.)\n");
was_read_correctly = 0;
} else if ( * endptr && '\n' != * endptr) {
fprintf(stderr, "Input didn't get wholely converted.\n(Entered digits and characters)\n");
was_read_correctly = 0;
}
} else {
fprintf(stderr, "Input was not read correctly.\n");
was_read_correctly = 0;
}
return was_read_correctly;
}
How should I think/plan the process of stubbing a function like fgets/malloc in C? And, if it isn't too much, how a function like this should be thought to test?
Disclaimer: This is just one way to mock C functions for GoogleTest. There are other methods for sure.
The problem to mock C functions lays in the way GoogleTest works. All its cool functionality is based on deriving a C++ class to mock and overriding its methods. These methods must be virtual, too. But C function are no members of any class, left alone of being virtual.
The way we found and use with success it to provide a kind of wrapper class that includes methods that have the same prototype as the C functions. Additionally this class holds a pointer to an instance of itself as a static class variable. In some sense this resembles the Singleton pattern, with all its characteristics, for good or bad.
Each test instantiates an object of this class and uses this object for the common checks.
Finally the C functions are implemented as stubs that call the single instance's method of the same kind.
Let's say we have these C functions:
// cfunction.h
#ifndef C_FUNCTION_H
#define C_FUNCTION_H
extern "C" void cf1(int p1, void* p2);
extern "C" int cf2(void);
#endif
Then the header file for the mocking class is:
// CFunctionMock.h
#ifndef C_FUNCTION_MOCK_H
#define C_FUNCTION_MOCK_H
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "cfunction.h"
class CFunctionMock
{
public:
static CFunctionMock* instance;
CFunctionMock() {
instance = this;
}
~CFunctionMock() {
instance = nullptr;
}
MOCK_METHOD(void, cf1, (int p1, void* p2));
MOCK_METHOD(int, cf2, (void));
};
#endif
And this is the implementation of the mocking class, including the replacing C functions. All the functions check that the single instance exists.
// CFunctionMock.cpp
#include "CFunctionMock.h"
CFunctionMock* CFunctionMock::instance = nullptr;
extern "C" void cf1(int p1, void* p2) {
ASSERT_NE(CFunctionMock::instance, nullptr);
CFunctionMock::instance->cf1(p1, p2);
}
extern "C" int cf2(void) {
if (CFunctionMock::instance == nullptr) {
ADD_FAILURE() << "CFunctionMock::instance == nullptr";
return 0;
}
return CFunctionMock::instance->cf2();
}
On non-void function you can't use ASSERT_NE because it quits on an error with a simple return. Therefore the check for an existing instance is a bit more elaborated. You should think of a good default value to return, too.
Now we get to write some test.
// SomeTest.cpp
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::_;
using ::testing::Return;
#include "CFunctionMock.h"
#include "module_to_test.h"
TEST(AGoodTestSuiteName, AndAGoodTestName) {
CFunctionMock mock;
EXPECT_CALL(mock, cf1(_, _))
.Times(0);
EXPECT_CALL(mock, cf2())
.WillRepeatedly(Return(23));
// any call of module_to_test that calls (or not) the C functions
// any EXPECT_...
}
EDIT
I was reading the question once more and came to the conclusion that a more direct example is necessary. So here we go! I like to use as much of the magic behind Googletest because it makes extensions so much easier. Working around it feels like working against it.
Oh, my system is Windows 10 with MinGW64.
I'm a fan of Makefiles:
TESTS := Test
WARNINGLEVEL := -Wall -Wextra
CC := gcc
CFLAGS := $(WARNINGLEVEL) -g -O3
CXX := g++
CXXFLAGS := $(WARNINGLEVEL) -std=c++11 -g -O3 -pthread
LD := g++
LDFLAGS := $(WARNINGLEVEL) -g -pthread
LIBRARIES := -lgmock_main -lgtest -lgmock
GTESTFLAGS := --gtest_color=no --gtest_print_time=0
all: $(TESTS:%=%.exe)
run: all $(TESTS:%=%.log)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $#
%.o: %.cpp
$(CXX) $(CXXFLAGS) -I./include -c $< -o $#
%.exe: %.o
$(LD) $(LDFLAGS) $^ -L./lib $(LIBRARIES) -o $#
%.log: %.exe
$< $(GTESTFLAGS) > $# || type $#
Test.exe: module_to_test.o FgetsMock.o
These Makefiles make it easy to add more tests, modules, anything, and document all options. Extend it to your liking.
Module to Test
To get no warning, I had to extend the provided source:
// module_to_test.c
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "module_to_test.h"
// all the rest is as in the OP's source...
And of course we need a header file:
// module_to_test.h
#include <stdint.h>
int validate_input(uint32_t *input_value);
The Mock Class
The mock class is modelled after the example above. Do enable "feeding" the string I added an parameterized action.
// FgetsMock.h
#ifndef FGETS_MOCK_H
#define FGETS_MOCK_H
#include <cstring>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
ACTION_P(CopyFromSource, source)
{
memcpy(arg0, source, arg1);
}
class FgetsMock
{
public:
static FgetsMock* instance;
FgetsMock()
{
instance = this;
}
~FgetsMock()
{
instance = nullptr;
}
MOCK_METHOD(char*, fgets, (char*, int, FILE*));
};
#endif
Its implementation file is straight forward and provides the mocked C function.
// FgetsMock.cpp
#include <stdio.h>
#include "FgetsMock.h"
FgetsMock* FgetsMock::instance = nullptr;
extern "C" char* fgets(char* str, int num, FILE* stream)
{
if (FgetsMock::instance == nullptr)
{
ADD_FAILURE() << "FgetsMock::instance == nullptr";
return 0;
}
return FgetsMock::instance->fgets(str, num, stream);
}
Implementing Some Tests
Here are some examples for tests. Unfortunately the module-to-test uses stdout and stderr that are not so simple to catch and test. You might like to read about "death tests" or provide your own method of redirection. In the core, the design of the function is not that good, because it did not take testing into account.
// Test.cpp
#include "gmock/gmock.h"
#include "gtest/gtest.h"
using ::testing::_;
using ::testing::DoAll;
using ::testing::Ge;
using ::testing::NotNull;
using ::testing::Return;
using ::testing::ReturnArg;
#include "FgetsMock.h"
extern "C"
{
#include "module_to_test.h"
}
TEST(ValidateInput, CorrectInput)
{
const char input[] = "42";
const int input_length = sizeof input;
FgetsMock mock;
uint32_t number;
EXPECT_CALL(mock, fgets(NotNull(), Ge(input_length), stdin))
.WillOnce(DoAll(
CopyFromSource(input),
ReturnArg<0>()
));
int result = validate_input(&number);
EXPECT_EQ(result, 1);
EXPECT_EQ(number, 42U);
}
TEST(ValidateInput, InputOutputError)
{
FgetsMock mock;
uint32_t dummy;
EXPECT_CALL(mock, fgets(_, _, _))
.WillOnce(Return(nullptr));
int result = validate_input(&dummy);
EXPECT_EQ(result, 0);
}
TEST(ValidateInput, NegativeInput)
{
const char input[] = "-23";
const int input_length = sizeof input;
FgetsMock mock;
uint32_t dummy;
EXPECT_CALL(mock, fgets(NotNull(), Ge(input_length), stdin))
.WillOnce(DoAll(
CopyFromSource(input),
ReturnArg<0>()
));
int result = validate_input(&dummy);
EXPECT_EQ(result, 0);
}
TEST(ValidateInput, RangeError)
{
const char input[] = "12345678901";
const int input_length = sizeof input;
FgetsMock mock;
uint32_t dummy;
EXPECT_CALL(mock, fgets(NotNull(), Ge(input_length), stdin))
.WillOnce(DoAll(
CopyFromSource(input),
ReturnArg<0>()
));
int result = validate_input(&dummy);
EXPECT_EQ(result, 0);
}
TEST(ValidateInput, CharacterError)
{
const char input[] = "23fortytwo";
const int input_length = sizeof input;
FgetsMock mock;
uint32_t dummy;
EXPECT_CALL(mock, fgets(NotNull(), Ge(input_length), stdin))
.WillOnce(DoAll(
CopyFromSource(input),
ReturnArg<0>()
));
int result = validate_input(&dummy);
EXPECT_EQ(result, 0);
}
Building and Running the Tests
This is the output of my (Windows) console when building freshly and testing:
> make run
gcc -Wall -Wextra -g -O3 -c module_to_test.c -o module_to_test.o
g++ -Wall -Wextra -std=c++11 -g -O3 -pthread -I./include -c FgetsMock.cpp -o FgetsMock.o
g++ -Wall -Wextra -std=c++11 -g -O3 -pthread -I./include -c Test.cpp -o Test.o
g++ -Wall -Wextra -g -pthread Test.o module_to_test.o FgetsMock.o -L./lib -lgmock_main -lgtest -lgmock -o Test.exe
Test.exe --gtest_color=no --gtest_print_time=0 > Test.log || type Test.log
Input was not read correctly.
Negative number not allowed.
Input was not read correctly.
Sorry, this number is too small or too large.
Input didn't get wholely converted.
(Entered digits and characters)
rm Test.o
You see the output of stderr of the C function.
And this is the recorded log, see the Makefile how it is produced.
Running main() from gmock_main.cc
[==========] Running 5 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 5 tests from ValidateInput
[ RUN ] ValidateInput.CorrectInput
Give the value for which to print the bits: [ OK ] ValidateInput.CorrectInput
[ RUN ] ValidateInput.InputOutputError
Give the value for which to print the bits: [ OK ] ValidateInput.InputOutputError
[ RUN ] ValidateInput.NegativeInput
Give the value for which to print the bits: [ OK ] ValidateInput.NegativeInput
[ RUN ] ValidateInput.RangeError
Give the value for which to print the bits: [ OK ] ValidateInput.RangeError
[ RUN ] ValidateInput.CharacterError
Give the value for which to print the bits: [ OK ] ValidateInput.CharacterError
[----------] Global test environment tear-down
[==========] 5 tests from 1 test suite ran.
[ PASSED ] 5 tests.
Because of the output on stdout it is mixed up with Googletest's output.
I have managed to solve this issue in the following way:
header file for the stub function:
#ifndef STUBS_H_
#define STUBS_H_
#include "../src/p1.h"
char* fgets_stub(char *s, int size, FILE *stream);
#define fgets fgets_stub
#include "../src/p1.c"
char* fgets_RET;
#endif
implementation of stub function:
#include "stubs.h"
char* fgets_stub(char *s, int size, FILE *stream)
{
if (NULL != fgets_RET)
{
strcpy(s,fgets_RET);
}
return fgets_RET;
}
how to test in test.cpp:
TEST(ValidateInput,CorrectionTest)
{
uint32_t tester = 0;
char* dummy_char = new char[NUM_OF_BITS];
strcpy(dummy_char,"39131");
cout<<dummy_char;
fgets_RET = dummy_char;
ASSERT_EQ(1,validate_input(&tester));
}
if the person that tests wishes to force NULL return of fgets:
TEST(ValidateInput,CorrectionTest)
{
uint32_t tester = 0;
fgets_RET = NULL;
ASSERT_EQ(0,validate_input(&tester));
}

Weird pointer conversion in C

I'm having trouble while writing my garbage collector in C. I give you a minimal and verifiable example for it.
The first file is in charge of dealing with the virtual machine
#include <stdlib.h>
#include <stdint.h>
typedef int32_t value_t;
typedef enum {
Lb, Lb1, Lb2, Lb3, Lb4, Lb5,
Ib, Ob
} reg_bank_t;
static value_t* memory_start;
static value_t* R[8];
value_t* engine_get_Lb(void) { return R[Lb]; }
value_t engine_run() {
memory_start = memory_get_start();
for (reg_bank_t pseudo_bank = Lb; pseudo_bank <= Lb5; ++pseudo_bank)
R[pseudo_bank] = memory_start + (pseudo_bank - Lb) * 32;
value_t* block = memory_allocate();
}
Then I have the actual garbage collector, the minimized code is:
#include <stdlib.h>
#include <stdint.h>
typedef int32_t value_t;
static value_t* memory_start = NULL;
void memory_setup(size_t total_byte_size) {
memory_start = calloc(total_byte_size, 1);
}
void* memory_get_start() { return memory_start; }
void mark(value_t* base){
value_t vbase = 0;
}
value_t* memory_allocate() {
mark(engine_get_Lb());
return engine_get_Lb();
}
Finally, minimal main is:
int main(int argc, char* argv[]) {
memory_setup(1000000);
engine_run();
return 0;
}
The problem I'm getting with gdb is that if I print engine_get_Lb() I get the address (value_t *) 0x7ffff490a800 while when printing base inside of the function mark I get the address (value_t *) 0xfffffffff490a800.
Any idea why this is happening?
Complementary files that may help
The makefile
SHELL=/bin/bash
SRCS=src/engine.c \
src/main.c \
src/memory_mark_n_sweep.c
CFLAGS_COMMON=-std=c11 -fwrapv
CLANG_SAN_FLAGS=-fsanitize=address
# Clang warning flags
CLANG_WARNING_FLAGS=-Weverything \
-Wno-format-nonliteral \
-Wno-c++98-compat \
-Wno-gnu-label-as-value
# Flags for debugging:
CFLAGS_DEBUG=${CFLAGS_COMMON} -g ${CLANG_SAN_FLAGS} ${CLANG_WARNING_FLAGS}
# Flags for maximum performance:
CFLAGS_RELEASE=${CFLAGS_COMMON} -O3 -DNDEBUG
CFLAGS=${CFLAGS_DEBUG}
all: vm
vm: ${SRCS}
mkdir -p bin
clang ${CFLAGS} ${LDFLAGS} ${SRCS} -o bin/vm
File with instructions .asm
5c190000 RALO(Lb,25)
value_t* memory_allocate() {
mark(engine_get_Lb());
return engine_get_Lb();
}
engine_get_Lb is not declared before use. It is assumed by the compiler to return int, per an antiquated and dangerous rule of the C language. It was deprecated in the C standard for quite some time, and now is finally removed.
Create a header file with declarations of all your global functions, and #include it in all your source files.
Your compiler should have at least warned you about this error at its default settings. If it did, you should have read and completely understood the warnings before continuing. If it didn't, consider an upgrade. If you cannot upgrade, permanently add -Wall -Wextra -Werror to your compilation flags. Consider also -Wpedantic and -std=c11.

gcc __builtin_expect doesn't seem to generate a correct code

The following two code snippets produces exactly the same assembly code, even though branches are enclosed with different branch predictions.
Let's say that we have test0.c
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
int bar0();
int bar1();
int bar2();
int bar3();
int foo(int arg0) {
if (likely(arg0 > 100)) {
return bar0();
} else if (likely(arg0 < -100)) {
return bar1();
} else if (likely(arg0 > 0)) {
return bar2();
} else {
return bar3();
}
}
and test1.c
#define likely(x) __builtin_expect((x), 1)
#define unlikely(x) __builtin_expect((x), 0)
int bar0();
int bar1();
int bar2();
int bar3();
int foo(int arg0) {
if (unlikely(arg0 > 100)) {
return bar0();
} else if (unlikely(arg0 < -100)) {
return bar1();
} else if (unlikely(arg0 > 0)) {
return bar2();
} else {
return bar3();
}
}
As you can see by comparing two snippets, these two have different branch predictions for each branch (likely() vs. unlikely()).
However, when it is compiled from a linux box(ubuntu 12.04 32bit, gcc 4.6.3). These two sources produce virtually same outputs.
$gcc -c -S -o test0.s test0.c
$gcc -c -S -o test1.s test1.c
$ diff test0.s test1.s
1c1
< .file "test0.c"
---
> .file "test1.c"
If anyone can explain this, it will be a big help.
Thanks for your help in advance!
The two files you've posted are identical -- I assume this isn't what you've really done.
Compile with -O2 or higher, you need to turn on optimisation. This should then generate different code.
I did some measurements on ARM7 (Allwinner sun71 A20), and with gcc 6.3 (-O3) and there was no performance difference between #likely and #unlikely even though it was clear from other tests that taking a branch was more expensive than not taking it, even in the case of perfect branch prediction.

learning sample of likely() and unlikely() compiler hints

How can I demonstrate for students the usability of likely and unlikely compiler hints (__builtin_expect)?
Can you write an sample code, which will be several times faster with these hints comparing the code without hints.
Here is the one I use, a really inefficient implementation of the Fibonacci numbers:
#include <stdio.h>
#include <inttypes.h>
#include <time.h>
#include <assert.h>
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
uint64_t fib(uint64_t n)
{
if (opt(n == 0 || n == 1)) {
return n;
} else {
return fib(n - 2) + fib(n - 1);
}
}
int main(int argc, char **argv)
{
int i, max = 45;
clock_t tm;
if (argc == 2) {
max = atoi(argv[1]);
assert(max > 0);
} else {
assert(argc == 1);
}
tm = -clock();
for (i = 0; i <= max; ++i)
printf("fib(%d) = %" PRIu64 "\n", i, fib(i));
tm += clock();
printf("Time elapsed: %.3fs\n", (double)tm / CLOCKS_PER_SEC);
return 0;
}
To demonstrate, using GCC:
~% gcc -O2 -Dopt= -o test-nrm test.c
~% ./test-nrm
...
fib(45) = 1134903170
Time elapsed: 34.290s
~% gcc -O2 -Dopt=unlikely -o test-opt test.c
~% ./test-opt
...
fib(45) = 1134903170
Time elapsed: 33.530s
A few hundred milliseconds less. This gain is due to the programmer-aided branch prediction.
But now, for what the programmer should really be doing instead:
~% gcc -O2 -Dopt= -fprofile-generate -o test.prof test.c
~% ./test.prof
...
fib(45) = 1134903170
Time elapsed: 77.530s /this run is slowed down by profile generation.
~% gcc -O2 -Dopt= -fprofile-use -o test.good test.c
~% ./test.good
fib(45) = 1134903170
Time elapsed: 17.760s
With compiler-aided runtime profiling, we managed to reduce from the original 34.290s to 17.760s. Much better than with programmer-aided branch prediction!
From this blog post. I think likely and unlikely are mostly obsolete. Very cheap CPUs (ARM Cortex A20 in the example) have branch predictors and there is no penalty regardless of jump is taken / jump is not taken. When you introduce likely/unlikely the results will be either the same or worse (because compiler has generated more instructions).

Resources