4

Is there a C pre-processor string manipulation that could be used to extract substring from given string ?

I want to divide hexadecimal string representing __uint128 number into two hexadecimal 64bit chunks in order to produce 128bit number for given type.

As in pseudocode:

#include <inttypes.h>
#include <ctype.h>

#define UINT128_C(X)   // extraxt hi (0x == 2) + (ffffffffffffffff == 16) == 18
                       // extract lo (ffffffffffffffff == 16) 
                       // prepend lo with string "0x"                     == 18
                       // (((uint128_t)(hi) << 64) | (uint128_t)(lo))

typedef __uint128_t     uint128_t;

uint128_t x;

x = UINT128_C( 0xffffffffffffffffffffffffffffffff );
15
  • I doubt this is possible. Why is using two integer constants not acceptable? Oh, and Clang actually does support 128-bit integer constants with -fms-extensions. Commented Jul 2, 2015 at 17:41
  • @cremno It is acceptable, and I have implemented this solution, but estetic factor plays role in this case as in pseudocode. I can imagine that it can be done, as link has UINT128_C and somehow uses it for bit manipulation, ... but in source code there is no definition of UINT128_C, and I cant compile source code with success. Commented Jul 2, 2015 at 17:49
  • In my answer to your similar question, I already stated there is no standard support for _int128 and there is no standard type __uint128. Just read the standard. Or check gcc documentation for related extensions. Commented Jul 2, 2015 at 18:01
  • 1
    You might use a different pre-processor, e.g. m4; Afaik (which has only a very small basis, though) this might be able to to true text-processing, not just replacement. Commented Jul 2, 2015 at 19:04
  • 1
    Yes, m4 can do this job. If you happen to be configuring your project with GNU Autoconf, then you're using m4 already, and you have a convenient framework already in place for performing the preprocessing. Commented Jul 2, 2015 at 19:06

1 Answer 1

3

The C preprocessor cannot decompose tokens into smaller tokens, though it can replace them altogether in the special case that they are macro names. Thus, you cannot use it to physically split hexadecimal digit strings that you do not predict in advance.

You can use the preprocessor to convert the hexadecimal digit string into a C string, and perhaps then to wrap that in a conversion function, such as strtoull() (if that happened to be appropriate). If that function in particular were suitable, however, then you could also just use the the hex string as-is, or by pasting a ULL suffix onto it.

Sign up to request clarification or add additional context in comments.

15 Comments

Usiung a function will not yield an _integer constant_m however.
@Olaf, you are quite right that if the macro relies on a function to perform the conversion then the result cannot be used where a constant is required. That's not the case presented in the question, but it is an important consideration for using such an approach in a more general context. I don't think there is a solution to the problem, as presented, that affords a compile-time constant.
@John Bollinger Thank you for your answer. I do predict them in advance as there are my constants. String constants can be concatenated in pre-processing, but connot be chunked? Am i right ? strtoull or event strtoulll (coded) wouldnt be solution as it (in my opinion) unnecessarily complicates code.
I actually do understand the question that OP actually does want to generate constants: split the hexadecimal integer constant into two halves, cast each to uint64_t and then combine these value to a __uint128 with bitops. @DawidSzymański: Is that correct?
@Olaf, I'm just saying that in the OP's code snippet, the macro is used to produce the right-hand side of an assignment statement. The correctness of the resulting preprocessed statement does not rely on the macro yielding a constant.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.