I'm digging around the guts of numpy, trying to figure out why it's not building for me (64-bit Cygwin, Windows 8.1), I've come to this file.
When compilation hits the rad2deg() function (pasted below), I get a segfault. Looking at the file, there are a ton of '#' symbols sprinkled throughout the code. It looks like some kind of wildcard token, or a preprocessor token, but I can't find any info on it anywhere.
#define LOGE2 NPY_LOGE2#c#
#define LOG2E NPY_LOG2E#c#
#define RAD2DEG (180.0#c#/NPY_PI#c#)
#define DEG2RAD (NPY_PI#c#/180.0#c#)
#type# npy_rad2deg#c#(#type# x) {
return x*RAD2DEG;
}`
There are other places in the code where compiler doesn't choke with the '#' characters.
Can anyone point me to a search term that might explain this?
Okay, I've figured it out. This is what I get for posting a question after a long nap and a dose of cough medicine.
This is some non-standard pre-pre-processor trick, probably implemented in the Python code which builds the C code for numpy.
/**begin repeat
* #type = npy_float, npy_double, npy_longdouble#
* #c = f, ,l#
* #C = F, ,L#
*/
#define LOGE2 NPY_LOGE2#c#
#define LOG2E NPY_LOG2E#c#
#define RAD2DEG (180.0#c#/NPY_PI#c#)
#define DEG2RAD (NPY_PI#c#/180.0#c#)
#type# npy_rad2deg#c#(#type# x)
{
return x*RAD2DEG;
}
/**end repeat**/
It iterates across the code, replacing the #-surrounded tokens in the code with the tokens in the comment block, generating three nearly identical code blocks operating on different data types.
I suspect the segfault may be coming from improper data types; we'll see.
Thanks all!
Related
Nginx seems to have a built-in function called ngx_random that's used in various places of the source code. But it seems just to be defined as:#define ngx_random random
If I'm understanding this correctly, that means all the places Nginx calling ngx_random() it's just calling (on Linux platform) random(). From the doc it isn't clear to me that it is guaranteed uniform distribution with a given range in any way, and I'm suspecting that similar to rand(), it's not uniform at all, and will only be uniform if range n is divisible by RAND_MAX.
But the nice thing of using ngx_random is I believe the system takes care of the seeding automatically, during startup time. Whereas if I want to use something truly uniform with my range, like drand48, I believe will have to add a new line after the following in ngx_posix_init.c?
srandom(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec);
srand48(((unsigned) ngx_pid << 16) ^ tp->sec ^ tp->msec); //Added so that I can use drand48
So is my assumption on ngx_random correct? And if I want to use drand48 in any place of the various modules, is the above the only way doing it?
I never tried it myself with nginx, so consider it just an idea. On Linux (or similar ELF based systems, e.g. Solaris) you could, using LD_LIBRARY_PRELOAD trick, to replace and/or intercept weak symbols from standard C library. It is often used to intercept and/or replace malloc, but might work for you as well
Code sample (untested, not compiled, just to demonstrate an idea)
#define _GNU_SOURCE
#include <stdlib.h>
#include <dlfcn.h>
static void (*real_srandom)(uint32_t) = NULL;
static void srandom_init(void) {
real_srandom = dlsym(RTLD_NEXT, "srandom");
if (NULL == real_srandom) {
fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
}
}
void srandom(uint32_t seed) {
if(real_srandom == NULL) {
srandom_init();
}
real_srandom(seed);
srand48(seed);
}
You could write SO to replace calls to random(3) as well, replacing it with your own implementation. The only thing you cannot replace is RAND_MAX, as it is compiled in constant.
I would be happy to hear if this trick works for you or not
I would like to compute something according to the version of a library (which I can't change the values) by using C language.
However, the version of the library, that I am using, is defined as string by using #defines like:
/* major version */
#define MAJOR_VERSION "2"
/* minor version */
#define MINOR_VERSION "2"
Then, my question is: how to do define the macro STR_TO_INT in order to convert the strings MINOR_VERSION and MAJOR_VERSION to integer?
#if ((STR_TO_INT(MAJOR_VERSION) == 2 && STR_TO_INT(MINOR_VERSION) >= 2) || (STR_TO_INT(MAJOR_VERSION > 2))
//I perform an action...
#else
//I perform a different action
#endif
I prefer to define it as macro since I am using a lot of function from this library. Please feel free to give me any idea.
Preprocess the official library header, libheader.h, to generate your more useful information without the quotes in a new header, libversion.h:
sed -n -e '/^#define \(M[AI][JN]OR\)_VERSION "\([0-9][0-9]*\)".*/ {
s//#define NUM_\1_VERSION \2/p
}' libheader.h >libversion.h
You might need to be more flexible about allowing spaces and tabs around the separate parts of #, define and the macro name. I also assume there are no comments in the definition (trailing comments are handled):
/* This starts in column 1 - unlike the next line */
# define /* No comment here */ MAJOR_VERSION /* Nor here */ "2"
Now you can include both libheader.h and libversion.h and compare the numeric versions with impunity (as long as you get the expressions correct):
#include "libheader.h"
#include "libversion.h"
#if ((NUM_MAJOR_VERSION == 2 && NUM_MINOR_VERSION >= 2) || NUM_MAJOR_VERSION > 2)
…perform the new action…
#else
…perform the old action…
#endif
Strictly, the sed script will also convert MIJOR_VERSION and MANOR_VERSION; however, they're unlikely to appear in the library header, and you can ignore the generated numeric versions with ease. There are ways to deal with that if you really think it is an actual rather than hypothetical problem.
More seriously, if the library has complicated controls on the version information, it could be that a single header can masquerade as different versions of the library — there could be multiple lines defining the major and minor versions. If that's the case, you have to work a lot harder.
#define MAJOR_VERSION 2 will work anywhere, as an int, as you have, 2, there is no need for string/ conversions. You can directly do:
if (MAJOR_VERSION == 2) { /* version 2 */ }
else { /* not version 2 */ }
I have found this code for compareAndSwap in a StackOverflow answer:
boolean CompareAndSwapPointer(volatile * void * ptr,
void * new_value,
void * old_value) {
#if defined(_MSC_VER)
if (InterlockedCompareExchange(ptr, new_value, old_value) == old_value) return false;
else return true;
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
return __sync_bool_compare_and_swap(ptr, old_value, new_value);
#else
# error No implementation
#endif
}
Is this the most proper way of having portable fast code, (Except assembly inlining).
Also, one problem is that those specific builtin methods have different parameters and return values from one compiler to another, which may require some additional changes like the if then else in this example.
Also another problem would be the behavior of these builtin methods in the machine code level, do they behave exactly the same ? (e.g use the same assembly instructions)
Note: Another problem would be if there is many supported platforms not just (Windows and Linux) as in this example. The code might get very big.
I would use a Hardware Abstraction Layer, (HAL) that allows generic code to be common - and any portable source can be included and build for each platform.
In my opinion, this allows for better structured and more readable source.
To allow you to better understand this process I would suggest Google for finding examples and explanations.
Hopefully this brief answer helps.
[EDIT] I will attempt a simple example for Bionix, to show how to implement a HAL system...
Mr A wants his application to run on his 'Tianhe-2' and also his 'Amiga 500'. He has the cross compilers etc and will build both binaries on his PC. He want to read keys and print to the screen.
mrAMainApplication.c contains the following...
#include "hal.h"
// This gets called every time around the main loop ...
void mainProcessLoop( void )
{
unsigned char key = 0;
// scan key ...
key = hal_ReadKey();
if ( key != 0 )
{
hal_PrintChar( key );
}
}
He then creates a header file (Remember - this is an example, not working code! )...
He creates hal.h ...
#ifndef _HAL_H_
#define _HAL_H_
unsigned char hal_ReadKey( void );
unsigned char hal_PrintChar( unsigned char pKey );
#endif // _HAL_H_
Now Mr A needs two separate source files, one for his 'Tianhe-2' system and another for his Amiga 500...
hal_A500.c
void hal_ReadKey( void )
{
// Amiga related code for reading KEYBOARD
}
void hal_PrintChar( unsigned char pKey )
{
// Amiga related code for printing to a shell...
}
hal_Tianhe2_VERYFAST.c
void hal_ReadKey( void )
{
// Tianhe-2 related code for reading KEYBOARD
}
void hal_PrintChar( unsigned char pKey )
{
// Tianhe-2 related code for printing to a shell...
}
Mr A then - when building for the Amiga - builds mrAmainApplication.c and hal_A500.c
When building for the Tianhe-2 - he uses hal_Tianhe2_VERYFAST.c instead of hal_A500.c
Right - I've written this example with some humour, this is not ear-marked at anyone, just I feel it makes the example more interesting and hopefully aids in understanding.
Neil
In modern C, starting with C11, use _Atomic for the type qualification and atomic_compare_exchange_weak for the function.
The newer versions of gcc and clang are compliant to C11 and implement these operations in a portable way.
Take a look at ConcurrencyKit and possibly you can use higher level primitives which is probably what most of the time people really want. In contrast to HAL which somewhat OS specific, I believe CK works on Windows and with a number of non-gcc compilers.
But if you are just interested in how to implement "compare-and-swap" or atomic actions portably on a wide variety of C compilers, look and see how that code works. It is all open-source.
I suspect that the details can get messy and they are not something that in general will make for easy or interesting exposition here for the general public.
I just ran into an interesting phenomenon with msp430f5529 (TI launchpad). After trying different approaches I was able to find a solution, but I don't understand what is going on here.
This code is part of a timer interrupt service routine (ISR). The special function register (SFR) TA0IV is supposed to hold the value of the interrupt number that triggered the ISR.
1 unsigned int index;
2
3 index = TA0IV; // Gives wrong value: 19874
4 index = *((volatile unsigned int *) TA0IV_); // Correct value: 4
TA0IV is defined with macros here:
5 #define sfrw_(x,x_) volatile __MSPGCC_PERIPHERAL__ unsigned int x __asm__("__" #x)
6 #define sfrw(x,x_) extern sfrw_(x,x_)
7 #define TA0IV_ 0x036E /* Timer0_A5 Interrupt Vector Word */
8 sfrw(TA0IV, TA0IV_);
What does this part of the first macro on line 5 do?
asm("__" #x)
Why is there no "x_" on the right hand side in the macro on line 5?
Last and most important question: Why does the usual typecasting on line 4 work as expected, but the one on line 3 doesn't?
BTW I use gcc-4.7.0.
Edit: More info
9 #define __MSPGCC_PERIPHERAL__ __attribute__((__d16__))
1) The # is a preprocessor "stringify" operator. You can see the impact of this using the -E compiler switch. Google "c stringify" for details.
2) Couldn't say. It isn't required that all parameters get used, and apparently whoever wrote this decided they didn't need it.
3) I'll take a shot at this one, but since I don't have all the source code or the hardware and can't experiment, I probably won't get it quite right. Maybe close enough for what you need though.
The first thing to understand is what the asm bit is doing. Normally (ok, sometimes) when you declare a variable (foo), the compiler assigns its own 'internal' name to the variable (ie _foo). However, when interfacing with asm modules (or other languages), sometimes you need to be able to specify the exact name to use, not allowing the compiler to mangle it in any fashion. That's what this asm is doing (see Asm Labels). So when you brush aside all the #define nonsense, what you've got is:
extern volatile __MSPGCC_PERIPHERAL__ unsigned int TA0IV __asm__("__TA0IV");
Since the definition you have posted is "extern," presumably somewhere (not shown), there's a symbol named __TA0IV that's getting defined. And since accessing it isn't working right, it appears that it is getting MIS-defined.
With the caveat that I HAVEN'T TRIED THIS, I would find this to be somewhat more readable:
#define TA0IV_ 0x036E
inline int ReadInterruptNumber()
{
int retval;
asm volatile("movl (%c1), %0": "=rm" (retval) : "i" (TA0IV_));
return retval;
}
FWIW.
Is there a way to get the C/C++ preprocessor or a template or such to mangle/hash the __FILE__ and __LINE__ and perhaps some other external input like a build-number into a single short number that can be quoted in logs or error messages?
(The intention would be to be able to reverse it (to a list of candidates if its lossy) when needed when a customer quotes it in a bug report.)
You will have to use a function to perform the hashing and create a code from __LINE__ and __FILE__ as the C preprocessor is not able to do such complex tasks.
Anyway, you can take inspiration by this article to see if a different solution can be better suited to your situation.
Well... you could use something like:
((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__ )
It wouldn't be perfectly unique, but it might work for what you want. Could change those ORs to +, which might work better for some things.
Naturally, if you can actually create a hashcode, you'll probably want to do that.
I needed serial valuse in a project of mine and got them by making a template that specialized on __LINE__ and __FILE__ and resulted in an int as well as generating (as compile time output to stdout) a template specialization for it's inputs that resulted in the line number of that template. These were collected the first time through the compiler and then dumped into a code file and the program was compiled again. That time each location that the template was used got a different number.
(done in D so it might not be possible in C++)
template Serial(char[] file, int line)
{
prgams(msg,
"template Serial(char[] file : \"~file~"\", int line : "~line.stringof~")"
"{const int Serial = __LINE__;");
const int Serial = -1;
}
A simpler solution would be to keep a global static "error location" variable.
#ifdef DEBUG
#define trace_here(version) printf("[%d]%s:%d {%d}\n", version, __FILE__, __LINE__, errloc++);
#else
#define trace_here(version) printf("{%lu}\n", version<<16|errloc++);
#endif
Or without the printf.. Just increment the errloc everytime you cross a tracepoint. Then you can correlate the value to the line/number/version spit out by your debug builds pretty easily.
You'd need to include version or build number, because those error locations could change with any build.
Doesn't work well if you can't reproduce the code paths.
__FILE__ is a pointer into the constants segment of your program. If you output the difference between that and some other constant you should get a result that's independent of any relocation, etc:
extern const char g_DebugAnchor;
#define FILE_STR_OFFSET (__FILE__ - &g_DebugAnchor)
You can then report that, or combine it in some way with the line number, etc. The middle bits of FILE_STR_OFFSET are likely the most interesting.
Well, if you're displaying the message to the user yourself (as opposed to having a crash address or function be displayed by the system), there's nothing to keep you from displaying exactly what you want.
For example:
typedef union ErrorCode {
struct {
unsigned int file: 15;
unsigned int line: 12; /* Better than 5 bits, still not great
Thanks commenters!! */
unsigned int build: 5;
} bits;
unsigned int code;
} ErrorCode;
unsigned int buildErrorCodes(const char *file, int line, int build)
{
ErrorCode code;
code.bits.line=line & ((1<<12) - 1);
code.bits.build=build & ((1<< 5) - 1);
code.bits.file=some_hash_function(file) & ((1<<15) - 1);
return code.code;
}
You'd use that as
buildErrorCodes(__FILE__, __LINE__, BUILD_CODE)
and output it in hex. It wouldn't be very hard to decode...
(Edited -- the commenters are correct, I must have been nuts to specify 5 bits for the line number. Modulo 4096, however, lines with error messages aren't likely to collide. 5 bits for build is still fine - modulo 32 means that only 32 builds can be outstanding AND have the error still happen at the same line.)