Probably an error in variadic templates in ICC 12.1

Probably an error in variadic templates in ICC 12.1

Cannot compile the following code with ICC 12.1.0.233 but GCC 4.6.2 compiles it just fine.
Problem occurs when template function with variadic arguments is located inside struct or class. Global scope or namespace didn't trigger the bug.

#include 

static void next ()
{
	printf ("Endn");
}

template  void next (VALUE value, Args... args)
{
	printf ("Param: %in", value);
	next (args...);
}

struct Foo
{
	// FAIL
	template  static void test1 (int value1, Args... args)
	{
		printf ("Start: %i, %in", value1, sizeof...(Args));
		next (args...);
	}
};

// OK
template  void test2 (int value1, Args... args)
{
	printf ("Start: %i, %in", value1, sizeof...(Args));
	next (args...);
}

int main ()
{
	test2 (123, 1234, 5678);
	Foo::test1 (123, 1234, 5678);
}

ICC output:

.test2.cpp(20): error: expected a ")"
  		next (args...);
  		          ^
          detected during instantiation of "void Foo::test1(int, Args...) [with Args=]" at line 34
18 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Hello,

I've tried to reproduce the problem you described but "failed".
Are you running Linux* or Mac OS* X and which version?

Using 12.1.0.233, both Intel64 & IA32 to be sure, did not show any error. Just two warnings for Intel64 because of sizeof(...) returning longs (clash with %i).

Also the line number is off by one in your example. I suppose that's a copy and paste mistake (first line in listing is empty)?

Which compiler options have you used? Did you explicitly enable C++11 via -std=c++0x?

Best regards,

Georg Zitzlsberger

Thanks for your reply.

>> Are you running Linux* or Mac OS* X and which version?
I'm running on windows 2008R2.

>> Using 12.1.0.233, both Intel64 & IA32 to be sure, did not show any error.
Unfortunately I still able to reproduce the error.
Also I was able to reproduce the bug with Composer XE 2011 update 8 (fresh install in trial mode in VM on Windows 2003 SP2 x86 with MSVC 2008) - with same error.

------ Build started: Project: Test3, Configuration: Debug Win32 ------
Compiling with Intel C++ Compiler XE 12.1.2.278 [IA-32]... (Intel C++ Environment)
main2.cpp
.main2.cpp(20): error: expected a ")"
          next (args...);
                    ^
          detected during instantiation of "void Foo::test1(int, Args...) [with Args=]" at line 34

compilation aborted for .main2.cpp (code 2)
Build Time: 0:00:01
Test3 - 1 error(s), 0 warning(s), 0 remark(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

>> Also the line number is off by one in your example. I suppose that's a copy and paste mistake (first line in listing is empty)?
Yes, that line was inserted by mistake, sorry for that.

>> Which compiler options have you used? Did you explicitly enable C++11 via -std=c++0x?
I use Intel integration for MSVC 2008. My compile options are:

/c /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /RTC1 /MTd /GS /fp:fast /Fo"E:\Temp\Test3\Debug//" /Fd".\Debug/" /W3 /nologo /ZI /Qstd=c++0x

Hello,

for Windows*! Yes, that's the information I needed. Now I see the same problem (also using update 8).
I'll take a look what's wrong here.
May I tell you upfront that our compiler strives for to be compatible to VS compiler on Windows*, though. I cannot promise you anything about compatibility to GCC here (depends on how compatible GCC is to VS compiler on Windows*). There might be side effects.

Anyways, I'll check first and came back to you.

Best regards,

Georg Zitzlsberger

Hi,

>> I'll take a look what's wrong here.
Thanks!

>> May I tell you upfront that our compiler strives for to be compatible to
VS compiler on Windows*, though.
Honestly I don't think this is some kind of MSVC compatibility issue. Most likely this is C++0x implementation issue. According to C++0x standard variadic templates can be used in class methods, so the code is valid and hence should be compiled.

>> I cannot promise you anything about
compatibility to GCC here
I used GCC only to check that the code sample is valid and the code failed to compile because of compiler issue, so no GCC compatibility expected.

>> Anyways, I'll check first and came back to you.
Thank you very much!

Cheers,
Alex

Hello Alex,

I can confirm this being a bug in our compiler for Windows*; by the way: our compiler for Linux* does not fail here.
The example you provided is standards-compliant and we should support that.
We're working on a fix (DPD200178775). I'll let you know as soon as there is a new working version out.

Thank you a lot for providing such a nice reproducer!

Best regards,

Georg Zitzlsberger

Hi!

That's great! Thank you!
I glad I was able to help make ICC better.

Cheers,
Alex

Is there a workaround? What exactly triggers it? I just ran into this issue...

Same here with the update 9.Do you have any estimation date for a fix ?Thanks

Best Reply

Hello,

our compiler engineers are still working on that. I'm going to post a message here once we've fixed the problem and also name you the corresponding update release suitable for you.

With staying at the example from above, a workaround would be the following:

...

struct Foo  
{  
    template  static void test1 (int value1, Args... args);
};

template  void Foo::test1 (int value1, Args... args)  
{  
    printf ("Start: %i, %in", value1, sizeof...(Args));  
    next (args...);  
}

...

Definition of "test1(...)" has been pulled out of class body "Foo".
Does this approach help you all?

Best regards,

Georg Zitzlsberger

I can't get it to work that way; might be because in my case it's a templated constructor, or because it's in a namespace or just because I am not getting the syntax right (quite possible).
I have worked around it by now by "simply" not using it... attached is a reproduction of my code, just in case it's hitting some other bug near there.

class DLLockable {
//blah blah
};

namespace DLCL {
	template
	class Lockable : public DLLockable, public T {
		public:
			Lockable() {}

			template
			Lockable(Args... args) : T(args...) {}
	};
};

struct Data {

Data(int, int);

};

void testing();

void testing()

{

DLCL::Lockable theData(4, 4);

}

Yes, this is working for me. Even for template function inside template class.Thank you so much for this workaround.Cheers

Try this:

[C++]namespace DLCL {  
	template 
	class Lockable : public DLLockable, public T {  
	public:  
		Lockable() {}  

		template 
		Lockable(Args... args);  
	};  

	template 
	template  
	Lockable::Lockable (Args... args) : T(args...)
	{
		// Implementation
	}
};[/C++]

I've got even worse error trying to apply this workaround.
More details are here: http://software.intel.com/en-us/forums/showthread.php?t=103445

Hello gaelyvan,

did the proposal vom creatorcray (reply #12) help you?
If not you can try to set the following compiler option in "Command Line/Additional Options" (Property Pages/C/C++):

/Qoption,cpp,--parse_templates

This shouldn't require you to change the code at all.

Best regards,

Georg Zitzlsberger

Hello,

the original problem will be fixed with the next update Intel Composer XE 2011 Update 10.

Best regards,

Georg Zitzlsberger

This is a good news, thank you!

That can't get here soon enough, I just ran into the same bug again; at least reply #12 does work as a workaround for me this time...

Leave a Comment

Please sign in to add a comment. Not a member? Join today