Is it possible to make macros that are default arguments expand at call site?












1















#include <stdio.h>

void print(int a = __LINE__){printf("hello %dn", a);}

void main(){
print();
print();
print();
print();
}


The __LINE__ macro in this case expands to 3, so the print function is called 4 times with the same value. Is there a way to convince the compiler to expand this macro at the callsite, so that the print function would be called with 6,7,8,9 instead of 3,3,3,3 with features that exist in C++11?



My usecase:



In my application, I provide multiple functions that take a unique ID. The ID should be unique per callsite/location (so if the function is called two times throught the same statement, it should receive the same id). Currently, the user always has to manually type a LOCATION macro at the callsite, like this:



#define S1(x) #x //voodoo to concat __FILE__ and __LINE__
#define S2(x) S1(x)
#define LOCATION __FILE__ S2(__LINE__)

do_stuff1(arguments, LOCATION)
do_stuff2(arguments, LOCATION)


It would be more convenient if I could save them the typing, without creating a macro for each function like this:



#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))


Hence I thought a default argument would do the trick. Is there any way to achieve this?










share|improve this question




















  • 3





    Do the work in a macro, #define print() {printf("hello %dn", __LINE__);}.

    – Eljay
    Nov 20 '18 at 18:16











  • This is exactly what I wrote in the last code block, only translated on do_stuff instead of print. I am aware of this solution and wanted to know if there was a less tedious way to do this (I have quite a lot of these functions. I would need to make a macro for each of them).

    – pulp_user
    Nov 20 '18 at 18:19











  • Wait, no, sorry I was wrong. Your way makes the whole function a macro. That is indeed different. I will consider that, thanks!

    – pulp_user
    Nov 20 '18 at 18:22






  • 1





    @MatthieuBrucher Don't change the tags from C++ to C like that. Even if all of the code in the question would compile with a C compiler, that doesn't make the question a C question (note that default arguments are a C++ feature). The OP is using a C++ compiler and is looking for C++ answers, not C.

    – Justin
    Nov 20 '18 at 18:28


















1















#include <stdio.h>

void print(int a = __LINE__){printf("hello %dn", a);}

void main(){
print();
print();
print();
print();
}


The __LINE__ macro in this case expands to 3, so the print function is called 4 times with the same value. Is there a way to convince the compiler to expand this macro at the callsite, so that the print function would be called with 6,7,8,9 instead of 3,3,3,3 with features that exist in C++11?



My usecase:



In my application, I provide multiple functions that take a unique ID. The ID should be unique per callsite/location (so if the function is called two times throught the same statement, it should receive the same id). Currently, the user always has to manually type a LOCATION macro at the callsite, like this:



#define S1(x) #x //voodoo to concat __FILE__ and __LINE__
#define S2(x) S1(x)
#define LOCATION __FILE__ S2(__LINE__)

do_stuff1(arguments, LOCATION)
do_stuff2(arguments, LOCATION)


It would be more convenient if I could save them the typing, without creating a macro for each function like this:



#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))


Hence I thought a default argument would do the trick. Is there any way to achieve this?










share|improve this question




















  • 3





    Do the work in a macro, #define print() {printf("hello %dn", __LINE__);}.

    – Eljay
    Nov 20 '18 at 18:16











  • This is exactly what I wrote in the last code block, only translated on do_stuff instead of print. I am aware of this solution and wanted to know if there was a less tedious way to do this (I have quite a lot of these functions. I would need to make a macro for each of them).

    – pulp_user
    Nov 20 '18 at 18:19











  • Wait, no, sorry I was wrong. Your way makes the whole function a macro. That is indeed different. I will consider that, thanks!

    – pulp_user
    Nov 20 '18 at 18:22






  • 1





    @MatthieuBrucher Don't change the tags from C++ to C like that. Even if all of the code in the question would compile with a C compiler, that doesn't make the question a C question (note that default arguments are a C++ feature). The OP is using a C++ compiler and is looking for C++ answers, not C.

    – Justin
    Nov 20 '18 at 18:28
















1












1








1








#include <stdio.h>

void print(int a = __LINE__){printf("hello %dn", a);}

void main(){
print();
print();
print();
print();
}


The __LINE__ macro in this case expands to 3, so the print function is called 4 times with the same value. Is there a way to convince the compiler to expand this macro at the callsite, so that the print function would be called with 6,7,8,9 instead of 3,3,3,3 with features that exist in C++11?



My usecase:



In my application, I provide multiple functions that take a unique ID. The ID should be unique per callsite/location (so if the function is called two times throught the same statement, it should receive the same id). Currently, the user always has to manually type a LOCATION macro at the callsite, like this:



#define S1(x) #x //voodoo to concat __FILE__ and __LINE__
#define S2(x) S1(x)
#define LOCATION __FILE__ S2(__LINE__)

do_stuff1(arguments, LOCATION)
do_stuff2(arguments, LOCATION)


It would be more convenient if I could save them the typing, without creating a macro for each function like this:



#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))


Hence I thought a default argument would do the trick. Is there any way to achieve this?










share|improve this question
















#include <stdio.h>

void print(int a = __LINE__){printf("hello %dn", a);}

void main(){
print();
print();
print();
print();
}


The __LINE__ macro in this case expands to 3, so the print function is called 4 times with the same value. Is there a way to convince the compiler to expand this macro at the callsite, so that the print function would be called with 6,7,8,9 instead of 3,3,3,3 with features that exist in C++11?



My usecase:



In my application, I provide multiple functions that take a unique ID. The ID should be unique per callsite/location (so if the function is called two times throught the same statement, it should receive the same id). Currently, the user always has to manually type a LOCATION macro at the callsite, like this:



#define S1(x) #x //voodoo to concat __FILE__ and __LINE__
#define S2(x) S1(x)
#define LOCATION __FILE__ S2(__LINE__)

do_stuff1(arguments, LOCATION)
do_stuff2(arguments, LOCATION)


It would be more convenient if I could save them the typing, without creating a macro for each function like this:



#define do_stuff1(do_stuff1_imp(arguments, LOCATION))
#define do_stuff2(do_stuff2_imp(arguments, LOCATION))


Hence I thought a default argument would do the trick. Is there any way to achieve this?







c++ c++11 macros default-arguments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 18:27









Justin

13.5k95597




13.5k95597










asked Nov 20 '18 at 18:13









pulp_userpulp_user

465




465








  • 3





    Do the work in a macro, #define print() {printf("hello %dn", __LINE__);}.

    – Eljay
    Nov 20 '18 at 18:16











  • This is exactly what I wrote in the last code block, only translated on do_stuff instead of print. I am aware of this solution and wanted to know if there was a less tedious way to do this (I have quite a lot of these functions. I would need to make a macro for each of them).

    – pulp_user
    Nov 20 '18 at 18:19











  • Wait, no, sorry I was wrong. Your way makes the whole function a macro. That is indeed different. I will consider that, thanks!

    – pulp_user
    Nov 20 '18 at 18:22






  • 1





    @MatthieuBrucher Don't change the tags from C++ to C like that. Even if all of the code in the question would compile with a C compiler, that doesn't make the question a C question (note that default arguments are a C++ feature). The OP is using a C++ compiler and is looking for C++ answers, not C.

    – Justin
    Nov 20 '18 at 18:28
















  • 3





    Do the work in a macro, #define print() {printf("hello %dn", __LINE__);}.

    – Eljay
    Nov 20 '18 at 18:16











  • This is exactly what I wrote in the last code block, only translated on do_stuff instead of print. I am aware of this solution and wanted to know if there was a less tedious way to do this (I have quite a lot of these functions. I would need to make a macro for each of them).

    – pulp_user
    Nov 20 '18 at 18:19











  • Wait, no, sorry I was wrong. Your way makes the whole function a macro. That is indeed different. I will consider that, thanks!

    – pulp_user
    Nov 20 '18 at 18:22






  • 1





    @MatthieuBrucher Don't change the tags from C++ to C like that. Even if all of the code in the question would compile with a C compiler, that doesn't make the question a C question (note that default arguments are a C++ feature). The OP is using a C++ compiler and is looking for C++ answers, not C.

    – Justin
    Nov 20 '18 at 18:28










3




3





Do the work in a macro, #define print() {printf("hello %dn", __LINE__);}.

– Eljay
Nov 20 '18 at 18:16





Do the work in a macro, #define print() {printf("hello %dn", __LINE__);}.

– Eljay
Nov 20 '18 at 18:16













This is exactly what I wrote in the last code block, only translated on do_stuff instead of print. I am aware of this solution and wanted to know if there was a less tedious way to do this (I have quite a lot of these functions. I would need to make a macro for each of them).

– pulp_user
Nov 20 '18 at 18:19





This is exactly what I wrote in the last code block, only translated on do_stuff instead of print. I am aware of this solution and wanted to know if there was a less tedious way to do this (I have quite a lot of these functions. I would need to make a macro for each of them).

– pulp_user
Nov 20 '18 at 18:19













Wait, no, sorry I was wrong. Your way makes the whole function a macro. That is indeed different. I will consider that, thanks!

– pulp_user
Nov 20 '18 at 18:22





Wait, no, sorry I was wrong. Your way makes the whole function a macro. That is indeed different. I will consider that, thanks!

– pulp_user
Nov 20 '18 at 18:22




1




1





@MatthieuBrucher Don't change the tags from C++ to C like that. Even if all of the code in the question would compile with a C compiler, that doesn't make the question a C question (note that default arguments are a C++ feature). The OP is using a C++ compiler and is looking for C++ answers, not C.

– Justin
Nov 20 '18 at 18:28







@MatthieuBrucher Don't change the tags from C++ to C like that. Even if all of the code in the question would compile with a C compiler, that doesn't make the question a C question (note that default arguments are a C++ feature). The OP is using a C++ compiler and is looking for C++ answers, not C.

– Justin
Nov 20 '18 at 18:28














3 Answers
3






active

oldest

votes


















2















The __LINE__ macro in this case expands to 3




Sure because your function declaration is done at line 3 and the prepreprocessor expands it from there.



Another macro instead of a function declaration would do the trick well (taken from @Ejay's comment):



#define print() printf("hello %dn", __LINE__)


See a working example here.






share|improve this answer


























  • @Jarod42 Done that.

    – πάντα ῥεῖ
    Nov 20 '18 at 18:53



















4














You seem to be looking for std::experimental::source_location, which will be std::source_location in a future standard:



#include <experimental/source_location>

void print(std::experimental::source_location const& location
= std::experimental::source_location())
{
printf("hello %s:%dn", location.file_name(), location.line());
}





share|improve this answer



















  • 1





    This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

    – pulp_user
    Nov 20 '18 at 18:24






  • 1





    @pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

    – Justin
    Nov 20 '18 at 18:25





















0














You can write a macro which inserts the __FILE__ and __LINE__ into the argument list:



// Note: this doesn't work with a 0-argument function. Supporting 0-arg functions
// is much harder to do; I'd recommend just having a separate macro like as follows
#define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__)

#define LOCATED0(fn) fn(__FILE__, __LINE__)

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}

int do_something(int value, char const* file_name, int line);

int main() {
LOCATED0(print);
LOCATED(do_something, 42);
}


With a little more work, you can make it look nicer at the call-site:



#define LOCATED(...) LOCATED_##__VA_ARGS__

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}
#define LOCATED_print() ::print(__FILE__, __LINE__)

int do_something(int value, char const* file_name, int line);
#define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__)

int main() {
LOCATED(print());
LOCATED(do_something(42));
}





share|improve this answer


























  • I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

    – pulp_user
    Nov 20 '18 at 18:40








  • 1





    @pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

    – Justin
    Nov 20 '18 at 18:48











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53399081%2fis-it-possible-to-make-macros-that-are-default-arguments-expand-at-call-site%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









2















The __LINE__ macro in this case expands to 3




Sure because your function declaration is done at line 3 and the prepreprocessor expands it from there.



Another macro instead of a function declaration would do the trick well (taken from @Ejay's comment):



#define print() printf("hello %dn", __LINE__)


See a working example here.






share|improve this answer


























  • @Jarod42 Done that.

    – πάντα ῥεῖ
    Nov 20 '18 at 18:53
















2















The __LINE__ macro in this case expands to 3




Sure because your function declaration is done at line 3 and the prepreprocessor expands it from there.



Another macro instead of a function declaration would do the trick well (taken from @Ejay's comment):



#define print() printf("hello %dn", __LINE__)


See a working example here.






share|improve this answer


























  • @Jarod42 Done that.

    – πάντα ῥεῖ
    Nov 20 '18 at 18:53














2












2








2








The __LINE__ macro in this case expands to 3




Sure because your function declaration is done at line 3 and the prepreprocessor expands it from there.



Another macro instead of a function declaration would do the trick well (taken from @Ejay's comment):



#define print() printf("hello %dn", __LINE__)


See a working example here.






share|improve this answer
















The __LINE__ macro in this case expands to 3




Sure because your function declaration is done at line 3 and the prepreprocessor expands it from there.



Another macro instead of a function declaration would do the trick well (taken from @Ejay's comment):



#define print() printf("hello %dn", __LINE__)


See a working example here.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 '18 at 18:54









Jarod42

115k12101182




115k12101182










answered Nov 20 '18 at 18:21









πάντα ῥεῖπάντα ῥεῖ

72.6k974138




72.6k974138













  • @Jarod42 Done that.

    – πάντα ῥεῖ
    Nov 20 '18 at 18:53



















  • @Jarod42 Done that.

    – πάντα ῥεῖ
    Nov 20 '18 at 18:53

















@Jarod42 Done that.

– πάντα ῥεῖ
Nov 20 '18 at 18:53





@Jarod42 Done that.

– πάντα ῥεῖ
Nov 20 '18 at 18:53













4














You seem to be looking for std::experimental::source_location, which will be std::source_location in a future standard:



#include <experimental/source_location>

void print(std::experimental::source_location const& location
= std::experimental::source_location())
{
printf("hello %s:%dn", location.file_name(), location.line());
}





share|improve this answer



















  • 1





    This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

    – pulp_user
    Nov 20 '18 at 18:24






  • 1





    @pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

    – Justin
    Nov 20 '18 at 18:25


















4














You seem to be looking for std::experimental::source_location, which will be std::source_location in a future standard:



#include <experimental/source_location>

void print(std::experimental::source_location const& location
= std::experimental::source_location())
{
printf("hello %s:%dn", location.file_name(), location.line());
}





share|improve this answer



















  • 1





    This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

    – pulp_user
    Nov 20 '18 at 18:24






  • 1





    @pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

    – Justin
    Nov 20 '18 at 18:25
















4












4








4







You seem to be looking for std::experimental::source_location, which will be std::source_location in a future standard:



#include <experimental/source_location>

void print(std::experimental::source_location const& location
= std::experimental::source_location())
{
printf("hello %s:%dn", location.file_name(), location.line());
}





share|improve this answer













You seem to be looking for std::experimental::source_location, which will be std::source_location in a future standard:



#include <experimental/source_location>

void print(std::experimental::source_location const& location
= std::experimental::source_location())
{
printf("hello %s:%dn", location.file_name(), location.line());
}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 20 '18 at 18:18









JustinJustin

13.5k95597




13.5k95597








  • 1





    This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

    – pulp_user
    Nov 20 '18 at 18:24






  • 1





    @pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

    – Justin
    Nov 20 '18 at 18:25
















  • 1





    This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

    – pulp_user
    Nov 20 '18 at 18:24






  • 1





    @pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

    – Justin
    Nov 20 '18 at 18:25










1




1





This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

– pulp_user
Nov 20 '18 at 18:24





This is indeed exactly what I was looking for. I will not be able to use C++17 though (which this requires I think?). Sorry, I forgot to mention this in the question. I will keep this in mind for the future though. Thanks!

– pulp_user
Nov 20 '18 at 18:24




1




1





@pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

– Justin
Nov 20 '18 at 18:25







@pulp_user It doesn't require C++17, it requires that your standard library / compiler implements at least this part of the library fundamentals TS v2. You can try it and see if it works, else look at the documentation for your compiler / standard library to see if it works

– Justin
Nov 20 '18 at 18:25













0














You can write a macro which inserts the __FILE__ and __LINE__ into the argument list:



// Note: this doesn't work with a 0-argument function. Supporting 0-arg functions
// is much harder to do; I'd recommend just having a separate macro like as follows
#define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__)

#define LOCATED0(fn) fn(__FILE__, __LINE__)

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}

int do_something(int value, char const* file_name, int line);

int main() {
LOCATED0(print);
LOCATED(do_something, 42);
}


With a little more work, you can make it look nicer at the call-site:



#define LOCATED(...) LOCATED_##__VA_ARGS__

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}
#define LOCATED_print() ::print(__FILE__, __LINE__)

int do_something(int value, char const* file_name, int line);
#define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__)

int main() {
LOCATED(print());
LOCATED(do_something(42));
}





share|improve this answer


























  • I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

    – pulp_user
    Nov 20 '18 at 18:40








  • 1





    @pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

    – Justin
    Nov 20 '18 at 18:48
















0














You can write a macro which inserts the __FILE__ and __LINE__ into the argument list:



// Note: this doesn't work with a 0-argument function. Supporting 0-arg functions
// is much harder to do; I'd recommend just having a separate macro like as follows
#define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__)

#define LOCATED0(fn) fn(__FILE__, __LINE__)

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}

int do_something(int value, char const* file_name, int line);

int main() {
LOCATED0(print);
LOCATED(do_something, 42);
}


With a little more work, you can make it look nicer at the call-site:



#define LOCATED(...) LOCATED_##__VA_ARGS__

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}
#define LOCATED_print() ::print(__FILE__, __LINE__)

int do_something(int value, char const* file_name, int line);
#define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__)

int main() {
LOCATED(print());
LOCATED(do_something(42));
}





share|improve this answer


























  • I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

    – pulp_user
    Nov 20 '18 at 18:40








  • 1





    @pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

    – Justin
    Nov 20 '18 at 18:48














0












0








0







You can write a macro which inserts the __FILE__ and __LINE__ into the argument list:



// Note: this doesn't work with a 0-argument function. Supporting 0-arg functions
// is much harder to do; I'd recommend just having a separate macro like as follows
#define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__)

#define LOCATED0(fn) fn(__FILE__, __LINE__)

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}

int do_something(int value, char const* file_name, int line);

int main() {
LOCATED0(print);
LOCATED(do_something, 42);
}


With a little more work, you can make it look nicer at the call-site:



#define LOCATED(...) LOCATED_##__VA_ARGS__

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}
#define LOCATED_print() ::print(__FILE__, __LINE__)

int do_something(int value, char const* file_name, int line);
#define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__)

int main() {
LOCATED(print());
LOCATED(do_something(42));
}





share|improve this answer















You can write a macro which inserts the __FILE__ and __LINE__ into the argument list:



// Note: this doesn't work with a 0-argument function. Supporting 0-arg functions
// is much harder to do; I'd recommend just having a separate macro like as follows
#define LOCATED(fn, ...) fn(__VA_ARGS__, __FILE__, __LINE__)

#define LOCATED0(fn) fn(__FILE__, __LINE__)

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}

int do_something(int value, char const* file_name, int line);

int main() {
LOCATED0(print);
LOCATED(do_something, 42);
}


With a little more work, you can make it look nicer at the call-site:



#define LOCATED(...) LOCATED_##__VA_ARGS__

void print(char const* file_name, int line)
{
printf("hello %s:%dn", file_name, line);
}
#define LOCATED_print() ::print(__FILE__, __LINE__)

int do_something(int value, char const* file_name, int line);
#define LOCATED_do_something(value) ::do_something(value, __FILE__, __LINE__)

int main() {
LOCATED(print());
LOCATED(do_something(42));
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 '18 at 18:45

























answered Nov 20 '18 at 18:36









JustinJustin

13.5k95597




13.5k95597













  • I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

    – pulp_user
    Nov 20 '18 at 18:40








  • 1





    @pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

    – Justin
    Nov 20 '18 at 18:48



















  • I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

    – pulp_user
    Nov 20 '18 at 18:40








  • 1





    @pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

    – Justin
    Nov 20 '18 at 18:48

















I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

– pulp_user
Nov 20 '18 at 18:40







I fail to see how this is different from print(LOCATION) (how I currently do it in my code) besides turning it inside out.

– pulp_user
Nov 20 '18 at 18:40






1




1





@pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

– Justin
Nov 20 '18 at 18:48





@pulp_user You are right that it's not better than print(LOCATION), but it's an alternative

– Justin
Nov 20 '18 at 18:48


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53399081%2fis-it-possible-to-make-macros-that-are-default-arguments-expand-at-call-site%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith